diff --git a/src/ui/design-system/images/misc/roadmap-card-lg.png b/src/ui/design-system/images/misc/roadmap-card-lg.png new file mode 100644 index 0000000000..4e04d95701 Binary files /dev/null and b/src/ui/design-system/images/misc/roadmap-card-lg.png differ diff --git a/src/ui/design-system/images/misc/roadmap-card-sm.png b/src/ui/design-system/images/misc/roadmap-card-sm.png new file mode 100644 index 0000000000..eae6213ba4 Binary files /dev/null and b/src/ui/design-system/images/misc/roadmap-card-sm.png differ diff --git a/src/ui/design-system/images/misc/updates-dark.png b/src/ui/design-system/images/misc/updates-dark.png new file mode 100644 index 0000000000..a5eb22dd8f Binary files /dev/null and b/src/ui/design-system/images/misc/updates-dark.png differ diff --git a/src/ui/design-system/images/misc/updates-light.png b/src/ui/design-system/images/misc/updates-light.png new file mode 100644 index 0000000000..ca543e7edd Binary files /dev/null and b/src/ui/design-system/images/misc/updates-light.png differ diff --git a/src/ui/design-system/src/lib/Components/HomepageStartItem/HomepageStartIcons.tsx b/src/ui/design-system/src/lib/Components/HomepageStartItem/HomepageStartIcons.tsx index 58e465c156..8cf75c7984 100644 --- a/src/ui/design-system/src/lib/Components/HomepageStartItem/HomepageStartIcons.tsx +++ b/src/ui/design-system/src/lib/Components/HomepageStartItem/HomepageStartIcons.tsx @@ -12,6 +12,10 @@ import DevOfficeHours from '../../../../images/page/flow-dev-office-hours-icon.s import AssistantGpt from '../../../../images/page/flow-assistant-gpt-icon.svg'; import DeveloperChat from '../../../../images/page/flow-developer-chat-icon.svg'; import NetworkUpgrade from '../../../../images/page/flow-network-upgrade-icon.svg'; +import RoadmapLarge from '../../../../images/misc/roadmap-card-lg.png'; +import RoadmapSmall from '../../../../images/misc/roadmap-card-sm.png'; +import UpdatesLight from '../../../../images/misc/updates-light.png'; +import UpdatesDark from '../../../../images/misc/updates-dark.png'; export interface HomepageStartItemIconsProps { icon: string; } @@ -60,6 +64,21 @@ export function HomepageStartItemIcons({ /> ); + case 'roadmap': + return ( + <> + Roadmap + Roadmap + + ); case 'dev-office-hours': return ; case 'flow-assistant-gpt': @@ -68,6 +87,21 @@ export function HomepageStartItemIcons({ return ; case 'network-upgrade': return ; + case 'updates': + return ( + + Flow Blockchain Updates + Flow Blockchain Updates + + ); default: throw new Error(`Icon type not recognized ${icon}`); } diff --git a/src/ui/design-system/src/lib/Components/HomepageStartItem/index.tsx b/src/ui/design-system/src/lib/Components/HomepageStartItem/index.tsx index 8e52ea7868..e7843103fd 100644 --- a/src/ui/design-system/src/lib/Components/HomepageStartItem/index.tsx +++ b/src/ui/design-system/src/lib/Components/HomepageStartItem/index.tsx @@ -16,6 +16,7 @@ export function HomepageStartItem({ }: HomepageStartItemProps): React.ReactElement { return ( diff --git a/src/ui/design-system/src/lib/Components/HomepageStartList/SignUpSection.tsx b/src/ui/design-system/src/lib/Components/HomepageStartList/SignUpSection.tsx new file mode 100644 index 0000000000..37a5e980b6 --- /dev/null +++ b/src/ui/design-system/src/lib/Components/HomepageStartList/SignUpSection.tsx @@ -0,0 +1,124 @@ +import React, { useState } from 'react'; +import { HomepageStartItem } from '../HomepageStartItem'; +import { Button } from '../Button'; +import { HomepageStartItemIcons } from '../HomepageStartItem/HomepageStartIcons'; + +const roadmapData = { + link: 'https://flow.com/upgrade/crescendo/cadence-1#roadmap', + icon: 'roadmap', +}; +const SUCCESS_MESSAGE = 'Subscription successful!'; + +export function SignUpSection(): React.ReactElement { + const [email, setEmail] = useState(''); + const [errorMsg, setErrorMsg] = useState(''); + const [isSubmitting, setIsSubmitting] = useState(false); + const [responseMessage, setResponseMessage] = useState(''); + + const isValidEmail = (email: string): boolean => { + const re = + /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + return re.test(String(email).toLowerCase()); + }; + + const handleSubscribe = (): void => { + setIsSubmitting(true); + if (isValidEmail(email)) { + // Add here your logic to handle the email subscription + fetch('https://hooks.zapier.com/hooks/catch/12044331/3pv7v1t/', { + method: 'POST', + mode: 'no-cors', + headers: { + accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ email }), + }) + .then((response) => { + if (response.status === 0) { + // using no-cors mode, status is always 0 + setResponseMessage(SUCCESS_MESSAGE); + setEmail(''); + setErrorMsg(''); + } + }) + .catch((error) => { + console.error('Error:', error); + setErrorMsg('An error occurred.'); + }) + .finally(() => { + setIsSubmitting(false); + }); + } else { + setErrorMsg('Please enter a valid email address'); // Trigger some user feedback + } + }; + + return ( +
+
+ +
+ + + Flow Ecosystem Newsletter{' '} + +
+ Stay up to date with the latest changelog updates, educational + resources, grants and announcements. +
+ + {responseMessage !== SUCCESS_MESSAGE && ( + <> + { + setEmail(e.target.value.toLowerCase()); + if (e.target.value === '') { + setErrorMsg('Please enter your email'); + } + if (isValidEmail(email)) setErrorMsg(''); + }} + onBlur={(e) => { + if (e.target.value === '') { + setErrorMsg(''); + return; + } + setErrorMsg( + isValidEmail(email) ? '' : 'Please enter a valid email', + ); + }} + /> + + + )} + {errorMsg !== '' && ( +
{errorMsg}
+ )} + {errorMsg === '' && ( +
+ {SUCCESS_MESSAGE} +
+ )} +
+
+
+ ); +} diff --git a/src/ui/design-system/src/lib/Pages/HomePage/index.tsx b/src/ui/design-system/src/lib/Pages/HomePage/index.tsx index 7147d31a62..358c25669f 100644 --- a/src/ui/design-system/src/lib/Pages/HomePage/index.tsx +++ b/src/ui/design-system/src/lib/Pages/HomePage/index.tsx @@ -13,6 +13,7 @@ import { LinkGrid } from '../../Components/LinkGrid'; import { SocialCards } from '../../Components/SocialCards'; import BgImage from '../../../../images/misc/bg-social-section.jpg'; import TransitionPageSection from '../shared/TransitionPageSection'; +import { SignUpSection } from '../../Components/HomepageStartList/SignUpSection'; export type HomePageProps = SocialLinksSignupProps & { concepts?: TutorialCardProps[]; @@ -56,6 +57,11 @@ const HomePage = ({ discordUrl, githubUrl }: HomePageProps): JSX.Element => { > + + + + +
diff --git a/tailwind.config.js b/tailwind.config.js index c2f674dfa7..74ebcea950 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -50,6 +50,9 @@ module.exports = { display: 'Inter', mono: 'IBM Plex Mono', }, + transitionDuration: { + 2000: '2000ms', // Adding 2000ms duration + }, colors: { 'primary-green': '#00EF8B', 'primary-blue': '#3B3CFF',