Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Plugins Page #409

Merged
merged 5 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ NEXT_PUBLIC_SITE='https://amplication.com'
NEXT_PUBLIC_MAIL='contact@amplication.com'
NEXT_PRIVATE_HUBSPOT_PAT=''
NEXT_PRIVATE_BLOG_SERVER_URL='https://blog-api.amplication.com'
NEXT_PRIVATE_PLUGIN_API_URL='https://plugin-api.amplication.com'
NEXT_PUBLIC_BILLING_API_KEY='client-d3f38201-ed3a-4aea-af1d-1db1ad976ec0:415fb9ff-a378-42d0-a849-dae7daf49646'
1 change: 1 addition & 0 deletions .env.production
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ NEXT_PUBLIC_SITE='https://amplication.com'
NEXT_PUBLIC_MAIL='contact@amplication.com'
NEXT_PRIVATE_HUBSPOT_PAT=''
NEXT_PRIVATE_BLOG_SERVER_URL='https://blog-api.amplication.com'
NEXT_PRIVATE_PLUGIN_API_URL='https://plugin-api.amplication.com'
NEXT_PUBLIC_BILLING_API_KEY='client-d3f38201-ed3a-4aea-af1d-1db1ad976ec0:415fb9ff-a378-42d0-a849-dae7daf49646'


Expand Down
62 changes: 62 additions & 0 deletions components/Plugins/plugin-card.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import Image from 'next/image';
import PropTypes from 'prop-types';
import { useCallback } from 'react';
import * as analytics from '../../lib/analytics';
import Button from '../Common/Button';
import PluginLogo from './plugin-logo';

const Plugin = ({ plugin }) => {
const handleStartNowClick = useCallback((pluginId) => {
analytics.event({
action: 'startNowClicked',
params: {
buttonLocation: 'add-plugin-button',
pluginId,
},
});
}, []);

return (
<div
key={plugin.pluginId}
className={
'flex flex-col justify-between items-start overflow-hidden border border-solid border-dark-black-70 bg-purple-light h-full hover:shadow-hover-post rounded-lg p-4 min-h-[200px] '
}
>
<div className={'flex flex-row justify-start items-center '}>
<PluginLogo plugin={plugin} />
<div>
<div className="text-base">{plugin.name}</div>
</div>
</div>
<span className="text-xs text-gray py-4">{plugin.description}</span>
<div className="flex flex-row justify-between items-center mt-auto pt-4 w-full border-t-1 border-t-dark-black-70 ">
<span className="text-xs text-white">
<a href={plugin.github} target="github_plugin">
View Source
</a>
</span>
<span className="text-xs text-white">
<Button
text="Add Plugin"
backgroundColor="purpleBright"
hoverBackgroundColor="purpleBrightHover"
isLink={true}
onClick={() => {
handleStartNowClick(plugin.pluginId);
}}
href={`https://app.amplication.com/login?plugin-id=${plugin.pluginId}`}
className=" whitespace-nowrap !px-2 !py-2"
delayLinkMs={300} //add 300ms to be able to send the event
/>
</span>
</div>
</div>
);
};

Plugin.propTypes = {
plugin: PropTypes.object.isRequired,
};

export default Plugin;
29 changes: 29 additions & 0 deletions components/Plugins/plugin-logo.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Image from 'next/image';
import PropTypes from 'prop-types';

const PLUGIN_LOGO_BASE_URL =
'https://raw.githubusercontent.com/amplication/plugin-catalog/master/assets/icons/';

const PluginLogo = ({ plugin }) => {
return (
<span className="min-w-[60px] max-w-[60px] pr-4 flex flex-row justify-center items-center">
{plugin?.icon ? (
<Image
width={44}
height={44}
src={`${PLUGIN_LOGO_BASE_URL}${plugin.icon}`}
alt="plugin logo"
className="rounded-lg"
/>
) : (
<Image src={``} alt="plugin logo" />
)}
</span>
);
};

PluginLogo.propTypes = {
plugin: PropTypes.object.isRequired,
};

export default PluginLogo;
62 changes: 62 additions & 0 deletions components/Plugins/plugins-panel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import PropTypes from 'prop-types';
import PluginLogo from './plugin-logo';
import Link from 'next/link';

const PluginsPanel = ({ plugins }) => {
return (
<>
<h2 className="roadmap-heading tablet:text-center">Plugins</h2>
<div className="text-center">
Extend and customize your services by using plugins for various
technologies and integrations.
</div>
<div className="mt-8">
<div className=" flex items-center justify-center">
<div className="w-[200%] h-20 overflow-hidden relative">
<div className="w-[200%] flex items-center h-20 justify-around absolute left-0 animate ">
{plugins.map((plugin) => {
return (
<div
key={plugin.pluginId}
className="flex flex-row justify-center items-center whitespace-nowrap border border-solid border-dark-black-70 bg-purple-light rounded-lg p-2 px-3 m-2 font-normal "
>
<PluginLogo plugin={plugin} />
<span className="text-gray text-sm">{plugin.name}</span>
</div>
);
})}
{plugins.map((plugin) => {
return (
<div
key={plugin.pluginId}
className="flex flex-row justify-center items-center whitespace-nowrap border border-solid border-dark-black-70 bg-purple-light rounded-lg p-2 px-3 m-2 font-normal "
>
<PluginLogo plugin={plugin} />
<span className="text-gray text-sm">{plugin.name}</span>
</div>
);
})}
</div>
</div>
</div>
</div>
<div className="text-center mt-8">
<Link href="/plugins" passHref={true}>
<a className="btn btn-outline-light btn-lg mb-4 text-black80 btn-sm !h-[34px] !font-normal !text-sm px-4">
Show all plugins
</a>
</Link>
</div>
</>
);
};

PluginsPanel.propTypes = {
plugins: PropTypes.array,
};

PluginsPanel.defaultProps = {
plugins: [],
};

export default PluginsPanel;
1 change: 1 addition & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const nextConfig = {
'*.s3.amazonaws.com',
's3.amazonaws.com',
'www.facebook.com',
'raw.githubusercontent.com'
],
},
experimental: { images: { allowFutureImage: true }, optimizeCss: true },
Expand Down
94 changes: 46 additions & 48 deletions pages/_app.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ApolloProvider } from '@apollo/client';
import Head from 'next/head';
import Script from 'next/script';
import { useRouter } from 'next/router';
Expand All @@ -11,6 +10,7 @@ import '../styles/globals.css';
import '../styles/stigg.css';
import 'react-loading-skeleton/dist/skeleton.css';
import "../styles/bootstrap-wrapper.scss"
import "../styles/carousel.css"
import client from '../services/index';
import * as analytics from '../lib/analytics';

Expand Down Expand Up @@ -80,62 +80,60 @@ function Amplication({ Component, pageProps }) {
<Head>
<link rel="icon" href="/images/favicon.ico" />
</Head>
<ApolloProvider client={client}>
<DefaultSeo canonical={canonicalUrl} />
<DefaultSeo canonical={canonicalUrl} />

{getLayout(<Component {...pageProps} />)}
{/*Google Fonts*/}
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
rel="preconnect"
href="https://fonts.gstatic.com"
crossOrigin={'true'}
/>
{/* eslint-disable-next-line @next/next/no-page-custom-font */}
<link
href="https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Poppins:wght@300;400;500;600;700;800&family=Ubuntu+Mono&display=swap"
rel="stylesheet"
/>
{/*Facebook Pixel*/}
<Script
id={'facebook-pixel'}
strategy={'afterInteractive'}
dangerouslySetInnerHTML={{
__html: `
{getLayout(<Component {...pageProps} />)}
{/*Google Fonts*/}
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
rel="preconnect"
href="https://fonts.gstatic.com"
crossOrigin={'true'}
/>
{/* eslint-disable-next-line @next/next/no-page-custom-font */}
<link
href="https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Poppins:wght@300;400;500;600;700;800&family=Ubuntu+Mono&display=swap"
rel="stylesheet"
/>
{/*Facebook Pixel*/}
<Script
id={'facebook-pixel'}
strategy={'afterInteractive'}
dangerouslySetInnerHTML={{
__html: `
!function(e,t,n,c,o,a,f){e.fbq||(o=e.fbq=function(){o.callMethod?o.callMethod.apply(o,arguments):o.queue.push(arguments)},e._fbq||(e._fbq=o),o.push=o,o.loaded=!0,o.version="2.0",o.queue=[],(a=t.createElement(n)).async=!0,a.src="https://connect.facebook.net/en_US/fbevents.js",(f=t.getElementsByTagName(n)[0]).parentNode.insertBefore(a,f))}(window,document,"script"),fbq("init","694076677979309"),fbq("track","PageView");
`,
}}
/>
{/*Hotjar Tracking Code*/}
<Script
id={'hotjar'}
strategy={'lazyOnload'}
dangerouslySetInnerHTML={{
__html: `
}}
/>
{/*Hotjar Tracking Code*/}
<Script
id={'hotjar'}
strategy={'lazyOnload'}
dangerouslySetInnerHTML={{
__html: `
!function(t,h,e,j,s,n){t.hj=t.hj||function(){(t.hj.q=t.hj.q||[]).push(arguments)},t._hjSettings={hjid:2379815,hjsv:6},s=h.getElementsByTagName("head")[0],(n=h.createElement("script")).async=1,n.src="https://static.hotjar.com/c/hotjar-"+t._hjSettings.hjid+".js?sv="+t._hjSettings.hjsv,s.appendChild(n)}(window,document);
`,
}}
/>
<Script
id={'segment'}
strategy={'afterInteractive'}
dangerouslySetInnerHTML={{
__html: `
}}
/>
<Script
id={'segment'}
strategy={'afterInteractive'}
dangerouslySetInnerHTML={{
__html: `
!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on","addSourceMiddleware","addIntegrationMiddleware","setAnonymousId","addDestinationMiddleware"];analytics.factory=function(e){return function(){var t=Array.prototype.slice.call(arguments);t.unshift(e);analytics.push(t);return analytics}};for(var e=0;e<analytics.methods.length;e++){var key=analytics.methods[e];analytics[key]=analytics.factory(key)}analytics.load=function(key,e){var t=document.createElement("script");t.type="text/javascript";t.async=!0;t.src="https://cdn.segment.com/analytics.js/v1/" + key + "/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n);analytics._loadOptions=e};analytics._writeKey="GpXLWZ8HnAhUuUfZBs6bE5IE87yHmBtu";analytics.SNIPPET_VERSION="4.13.2";
analytics.load("GpXLWZ8HnAhUuUfZBs6bE5IE87yHmBtu");
}}();
`,
}}
/>
{/* Prevents HubSpot from loading form collector */}
<hs id={'CollectedForms-25691669'} />
{/* HubSpot */}
<Script
id={'hs-script-loader'}
strategy={'afterInteractive'}
src="//js-eu1.hs-scripts.com/25691669.js"
/>
</ApolloProvider>
}}
/>
{/* Prevents HubSpot from loading form collector */}
<hs id={'CollectedForms-25691669'} />
{/* HubSpot */}
<Script
id={'hs-script-loader'}
strategy={'afterInteractive'}
src="//js-eu1.hs-scripts.com/25691669.js"
/>
</>
);
}
Expand Down
51 changes: 48 additions & 3 deletions pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Facts from '../components/Sections/Enterprise/Facts';
import Testimonials from '../components/Sections/Enterprise/Testimonials';
import Features from '../components/Sections/MainPage/Features';
import GetList from '../components/Sections/MainPage/GetList';
import PluginsPanel from '../components/Plugins/plugins-panel';
import Tabs from '../components/Sections/MainPage/Tabs';
import Roadmap from '../components/Sections/MainPage/Roadmap';
import LogoList from '../components/Sections/About/LogoList';
Expand All @@ -12,7 +13,10 @@ import { MainLayout } from '../layouts';
import PageSection from '../components/Common/PageSection';
import Soc2Banner from '../components/Common/SOC2';

const Home = () => {
import { gql } from '@apollo/client';
import client from '../services/plugin-api';

const Home = ({ plugins }) => {
return (
<>
<NextSeo
Expand All @@ -37,15 +41,19 @@ const Home = () => {
<PageSection className={"page-welcome !pt-10 !pb-8 large:!py-[9vh] xlg:!py-[17vh]"}>
<HeroBlock />
</PageSection>
<PageSection className={'!pt-5 !pb-4 laptop:!py-20 '} innerClassName={"flex-grow"}>
<PageSection alternate className={'!pt-5 !pb-4 laptop:!py-20 '} innerClassName={"flex-grow"}>
<Slider />
</PageSection>
<PageSection alternate className={"page-welcome-solution !py-20"} >
<PageSection className={"page-welcome-solution !py-20"} >
<Features />
</PageSection>
<PageSection alternate>
<PluginsPanel plugins={plugins} />
</PageSection>
<PageSection innerClassName={"flex-grow"} className={"!pt-5 !pb-4 laptop:!px-14 laptop:!pt-24 laptop:!pb-20"} >
<Testimonials />
</PageSection>

<PageSection className={"!py-10"} alternate>
<Facts />
</PageSection>
Expand All @@ -70,6 +78,43 @@ const Home = () => {
</>
);
};

export const getServerSideProps = async (context) => {
try {
const { data } = await client.query({
query: gql`
query {
plugins {
id
pluginId
name
icon
description
taggedVersions
npm
github
website
}
}
`,
});
return {
props: {
plugins: data?.plugins
},
};
} catch (e) {
console.error(e);
}

return {
props: {
plugins: null,
},
};
};


Home.getLayout = function getLayout(page) {
return (
<MainLayout
Expand Down
Loading
Loading