Skip to content

Commit

Permalink
Add subscribe section (#720)
Browse files Browse the repository at this point in the history
* add new subscribe section

* add sub to email service backend

* remove logs and add error message

* add transistion when user submits email address

* use production subscribe endpoint

* fix jumping when error shows

* really fix jumping
  • Loading branch information
bthaile authored Apr 16, 2024
1 parent 2a3408c commit 005dcd6
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/ui/design-system/images/misc/updates-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -60,6 +64,21 @@ export function HomepageStartItemIcons({
/>
</>
);
case 'roadmap':
return (
<>
<img
className="hidden md:block w-full"
src={RoadmapLarge}
alt="Roadmap"
/>
<img
className="block md:hidden w-full"
src={RoadmapSmall}
alt="Roadmap"
/>
</>
);
case 'dev-office-hours':
return <DevOfficeHours />;
case 'flow-assistant-gpt':
Expand All @@ -68,6 +87,21 @@ export function HomepageStartItemIcons({
return <DeveloperChat />;
case 'network-upgrade':
return <NetworkUpgrade />;
case 'updates':
return (
<span>
<img
className="hidden dark:block"
src={UpdatesDark}
alt="Flow Blockchain Updates"
/>
<img
className="dark:hidden"
src={UpdatesLight}
alt="Flow Blockchain Updates"
/>
</span>
);
default:
throw new Error(`Icon type not recognized ${icon}`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export function HomepageStartItem({
}: HomepageStartItemProps): React.ReactElement {
return (
<AppLink
style={{ cursor: 'pointer' }}
className="flex w-full h-full cursor-pointer gap-6 rounded-lg text-white hover:text-white justify-center items-center hover:border-black transition-opacity duration-200 ease-out hover:opacity-90"
to={link}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -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<string>('');
const [errorMsg, setErrorMsg] = useState<string>('');
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 (
<div className="container md:p-0">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<HomepageStartItem key={0} {...roadmapData} />
<div className="flex flex-col gap-4 rounded-lg">
<HomepageStartItemIcons icon={'updates'} />
<span className="text-3xl font-semibold">
Flow Ecosystem Newsletter{' '}
</span>
<div className="text-primary-gray-300">
Stay up to date with the latest changelog updates, educational
resources, grants and announcements.
</div>

{responseMessage !== SUCCESS_MESSAGE && (
<>
<input
className="rounded-md p-4 border-0 text-primary-gray-300"
type="text"
value={email}
placeholder="Enter your email"
onChange={(e) => {
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',
);
}}
/>
<Button
onClick={handleSubscribe}
size={'sm'}
variant="accent"
className="p-4 border-0"
disabled={!isValidEmail(email)}
>
{isSubmitting ? 'Submitting' : 'Subscribe'}
</Button>
</>
)}
{errorMsg !== '' && (
<div className="min-h-[30px] text-red-500">{errorMsg}</div>
)}
{errorMsg === '' && (
<div
className={`min-h-[30px] transition-opacity duration-2000 ease-out ${
responseMessage === SUCCESS_MESSAGE
? 'opacity-100'
: 'opacity-0'
} align-center justify-center bg-primary-gray-400 rounded-lg text-primary-green p-4 w-full`}
>
{SUCCESS_MESSAGE}
</div>
)}
</div>
</div>
</div>
);
}
6 changes: 6 additions & 0 deletions src/ui/design-system/src/lib/Pages/HomePage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Expand Down Expand Up @@ -56,6 +57,11 @@ const HomePage = ({ discordUrl, githubUrl }: HomePageProps): JSX.Element => {
>
<LinkGrid />
</TransitionPageSection>
<TransitionPageSection sectionId="newsletter">
<PageSection>
<SignUpSection />
</PageSection>
</TransitionPageSection>
<div className="" style={{ backgroundImage: `url(${BgImage})` }}>
<TransitionPageSection sectionId="get-involved">
<SocialCards />
Expand Down
3 changes: 3 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down

0 comments on commit 005dcd6

Please sign in to comment.