Skip to content

Commit 2ca374e

Browse files
authored
feat: add new subscription component and improve footer design (asyncapi#568)
Co-authored-by: Aksshay88 <[email protected]>
1 parent e4cc1ee commit 2ca374e

File tree

8 files changed

+606
-190
lines changed

8 files changed

+606
-190
lines changed

components/Footer/changinghello.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"use client";
2+
import { Open_Sans } from "next/font/google";
3+
import React, { useEffect, useState } from "react";
4+
5+
const openSans = Open_Sans({ subsets: ["latin"] });
6+
7+
const thankyouList = [
8+
"thank you", // English
9+
"gracias", // Spanish
10+
"धन्यवाद", // Hindi
11+
"merci", // French
12+
"danke", // German
13+
"ありがとう", // Japanese
14+
"谢谢", // Chinese (Simplified)
15+
"Спасибо", // Russian
16+
"شكراً", // Arabic
17+
"감사합니다", // Korean
18+
"ευχαριστώ", // Greek
19+
"grazie", // Italian
20+
"terima kasih",// Indonesian/Malay
21+
"धन्यबाद", // Nepali
22+
"tack", // Swedish
23+
"dziękuję", // Polish
24+
"mersi", // Romanian
25+
"hvala", // Serbian/Croatian/Bosnian
26+
"धन्यवाद", // Marathi
27+
"ขอบคุณ", // Thai
28+
"ありがとう ございます", // Japanese (formal)
29+
"salamat", // Filipino (Tagalog)
30+
"धन्यवाद", // Sanskrit
31+
"მადლობა", // Georgian
32+
"спасибі", // Ukrainian
33+
"multumesc", // Romanian
34+
"tänan", // Estonian
35+
"aitäh", // Estonian (alternative)
36+
"faleminderit",// Albanian
37+
"شكرا جزيلا", // Arabic (formal)
38+
"धन्यवाद छ", // Maithili
39+
"děkuji", // Czech
40+
"kiitos", // Finnish
41+
"takk", // Norwegian
42+
"tak", // Danish
43+
];
44+
45+
function ChangingHello() {
46+
const [currthank, setCurrThank] = useState(thankyouList[0]);
47+
48+
useEffect(() => {
49+
const intervalId = setInterval(() => {
50+
const currentIndex = thankyouList.indexOf(currthank);
51+
const nextIndex = (currentIndex + 1) % thankyouList.length;
52+
setCurrThank(thankyouList[nextIndex]);
53+
}, 1500);
54+
55+
return () => {
56+
clearInterval(intervalId);
57+
};
58+
}, [currthank]);
59+
60+
return (
61+
<div
62+
className={`${openSans.className} md:pl-36 flex flex-col items-center justify-center text-6xl font-semibold`}
63+
>
64+
<p>
65+
{currthank === "شكراً" && "!"} {currthank}{" "}
66+
{currthank !== "شكراً" && "!"}
67+
</p>
68+
</div>
69+
);
70+
}
71+
72+
export default ChangingHello;

components/Footer/footer.js

+121-63
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,129 @@
1-
import React from "react";
2-
import Image from "next/image";
3-
import ILink from "../illustration/link";
1+
import Link from 'next/link';
2+
import React, { useEffect, useState } from 'react';
3+
import { Twitter, Github, Linkedin, Youtube, Slack, Twitch } from 'lucide-react';
4+
import Button from '../Buttons/button';
5+
const socialMediaLinks = [
6+
{ label: 'Twitter', url: 'https://twitter.com/AsyncAPISpec', icon: <Twitter className='h-5 w-5' /> },
7+
{ label: 'GitHub', url: 'https://github.com/asyncapi', icon: <Github className='h-5 w-5' /> },
8+
{ label: 'LinkedIn', url: 'https://linkedin.com/company/asyncapi', icon: <Linkedin className='h-5 w-5' /> },
9+
{ label: 'YouTube', url: 'https://youtube.com/asyncapi', icon: <Youtube className='h-5 w-5' /> },
10+
{ label: 'Slack', url: 'https://asyncapi.com/slack-invite', icon: <Slack className='h-5 w-5' /> },
11+
{ label: 'Twitch', url: 'https://www.twitch.tv/asyncapi', icon: <Twitch className='h-5 w-5' /> }
12+
];
13+
14+
const initiativeLinks = [
15+
{ label: 'About', url: '/about' },
16+
{ label: 'Venue', url: '/Venue' },
17+
{ label: 'Brand', url: 'https://github.com/asyncapi/brand/blob/master/brand-guidelines/README.md' },
18+
{ label: 'Tickets', url: '/tickets' },
19+
{ label: 'Speakers', url: '/speakers' },
20+
{ label: 'Code of Conduct', url: 'github.com/asyncapi/community/blob/master/CODE_OF_CONDUCT.md' }
21+
];
22+
23+
export default function ConferenceFooter() {
24+
const [helloText, setHelloText] = useState('Hello');
25+
const helloVariants = ["thank you", // English
26+
"gracias", // Spanish
27+
"धन्यवाद", // Hindi
28+
"merci", // French
29+
"danke", // German
30+
"ありがとう", // Japanese
31+
"谢谢", // Chinese (Simplified)
32+
"Спасибо", // Russian
33+
"شكراً", // Arabic
34+
"감사합니다", // Korean
35+
"ευχαριστώ", // Greek
36+
"grazie", // Italian
37+
"terima kasih",// Indonesian/Malay
38+
"धन्यबाद", // Nepali
39+
"tack", // Swedish
40+
"dziękuję", // Polish
41+
"mersi", // Romanian
42+
"hvala", // Serbian/Croatian/Bosnian
43+
"धन्यवाद", // Marathi
44+
"ขอบคุณ", // Thai
45+
"ありがとう ございます", // Japanese (formal)
46+
"salamat", // Filipino (Tagalog)
47+
"धन्यवाद", // Sanskrit
48+
"მადლობა", // Georgian
49+
"спасибі", // Ukrainian
50+
"multumesc", // Romanian
51+
"tänan", // Estonian
52+
"aitäh", // Estonian (alternative)
53+
"faleminderit",// Albanian
54+
"شكرا جزيلا", // Arabic (formal)
55+
"धन्यवाद छ", // Maithili
56+
"děkuji", // Czech
57+
"kiitos", // Finnish
58+
"takk", // Norwegian
59+
"tak", // Danish
60+
];
61+
62+
useEffect(() => {
63+
const interval = setInterval(() => {
64+
setHelloText(prev => helloVariants[(helloVariants.indexOf(prev) + 1) % helloVariants.length]);
65+
}, 3000);
66+
return () => clearInterval(interval);
67+
}, []);
468

5-
function Footer() {
6-
const socials = [
7-
{
8-
name: "Github",
9-
href: "https://github.com/asyncapi",
10-
imgUrl: "/img/Github.png",
11-
},
12-
{
13-
name: "Linkedin",
14-
href: "https://www.linkedin.com/company/asyncapi/",
15-
imgUrl: "/img/Linkedln.png",
16-
},
17-
{
18-
name: "Twitter(X)",
19-
href: "https://x.com/asyncapispec",
20-
imgUrl: "/img/twitter_new.png",
21-
},
22-
];
2369
return (
24-
<div className="container" data-test="footer">
25-
<div
26-
className="w-full flex justify-between items-center p-4 sm:flex-col sm:gap-3"
27-
data-test="footer-asyncAPI-logo"
28-
>
29-
<div className="mt-2 text-[14px] text-gray-100 sm:hidden">
30-
<a
31-
href="https://github.com/asyncapi/community/blob/master/CODE_OF_CONDUCT.md"
32-
target="_blank"
33-
rel="noreferrer"
34-
className="hover:underline text-white duration-200 ease-in-out flex items-center"
35-
data-test="code-of-conduct"
36-
>
37-
<span> Code of Conduct </span><span><ILink className='w-4 ml-2' fill='white' /></span>
38-
</a>
70+
<footer className='bg-dark px-6 py-14 text-white'>
71+
<div className='max-w-screen-xl mx-auto flex flex-col md:flex-row justify-between items-center text-center md:text-left'>
72+
73+
{/* Left: Logo & Description */}
74+
<div className='w-full md:w-1/4 flex flex-col items-start'>
75+
<Link href='/' aria-label='AsyncAPI Conference'>
76+
<img src='/img/logos/2025-logo.png' alt='AsyncAPI Logo' className='h-10 w-auto mb-4' />
77+
</Link>
78+
<p className='font-bold text-lg md:text-2xl mb-3'>A Global Gathering for <br /> API Experts, Architects, and Enthusiasts.
79+
</p>
3980
</div>
40-
<div></div>
41-
<div className="flex items-center justify-between sm:flex-col sm:items-center">
42-
<div className="text-white">© 2025 AsyncAPI.com – All rights reserved</div>
43-
<div className="w-[0.9px] h-4 bg-white ml-4 sm:hidden" />
44-
<div className="ml-4 flex justify-between items-center gap-2 sm:mt-4">
45-
{socials.map((social, index) => {
46-
return (
47-
<a
48-
key={index}
49-
href={social.href}
50-
target="_blank"
51-
rel="noreferrer"
52-
className="rounded-lg flex items-center justify-center hover:border-[#AD20E2] duration-150 ease-in-out"
53-
data-test={`footer-${social.name}`}
54-
>
55-
<Image
56-
src={social.imgUrl}
57-
alt={social.name}
58-
height={23}
59-
width={23}
60-
/>
81+
82+
{/* Center: The Conference (Adjusted Higher) & Follow Us */}
83+
<div className='w-full md:w-1/2 flex justify-between px-10'>
84+
<div className='w-full items-center mt-[-80px]'>
85+
<h3 className='font-bold text-lg md:text-2xl mb-3'>The Initiative</h3>
86+
<ul className='text-base'>
87+
{initiativeLinks.map((link, index) => (
88+
<li key={index} className='mb-2'>
89+
<Link href={link.url} className='hover:text-gray-300 transition duration-300 ease-in-out'>
90+
{link.label}
91+
</Link>
92+
</li>
93+
))}
94+
</ul>
95+
</div>
96+
<div className='flex flex-col items-center mt-[-80px] ml-[-500px] '>
97+
<h3 className='font-bold text-lg md:text-2xl mb-3 ml-[-30px]'>Follow Us</h3>
98+
<ul className='text-base'>
99+
{socialMediaLinks.map((link, index) => (
100+
<li key={index} className='mb-2 flex items-center'>
101+
<a href={link.url} target='_blank' rel='noopener noreferrer' className='flex items-center hover:text-gray-300'>
102+
{link.icon}
103+
<span className='ml-2'>{link.label}</span>
61104
</a>
62-
);
63-
})}
64-
</div>
105+
</li>
106+
))}
107+
</ul>
108+
</div>
65109
</div>
66110
</div>
67-
</div>
111+
112+
{/* Bottom Section */}
113+
<div className='border-t border-gray-600 mt-8 pt-6 flex flex-col md:flex-row justify-between items-center'>
114+
<p className='text-sm text-center md:text-left'>
115+
Made with <span className='font-mono text-secondary-500'>❤️</span> by the AsyncAPI Community.
116+
</p>
117+
<p className='text-sm text-center md:text-right mt-4 md:mt-0'>
118+
{helloText}
119+
</p>
120+
<p className='text-sm text-center md:text-right mt-4 md:mt-0'>
121+
Copyright &copy; AsyncAPI Conference. Powered by AsyncAPI Initiative.{' '}
122+
<a href='https://asyncapi.com' className='text-secondary-500 underline hover:text-gray-300' target='_blank' rel='noopener noreferrer'>
123+
asyncapi.com
124+
</a>
125+
</p>
126+
</div>
127+
</footer>
68128
);
69129
}
70-
71-
export default Footer;

components/Form/subscription.js

+48-18
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,50 @@
1-
import React from 'react';
2-
import Button from '../Buttons/button';
1+
import { useState } from 'react';
2+
import { motion } from 'framer-motion';
33

4-
function Subscription() {
5-
return (
6-
<div className='mt-0 md:mt-[106px] subscription container flex justify-center' >
7-
<div className='mt-[106px] lg:mt-0 w-[1024px] min-h-[253px] lg:py-10 lg:w-full flex flex-col items-center'>
8-
<h3 className='text-[32px] text-white lg:text-center'>
9-
Subscribe for AsyncAPI Conf updates!
10-
</h3>
11-
<a href='https://www.asyncapi.com/newsletter' target='_blank' rel="noreferrer" className='sm:w-full' data-test="subscribe-button">
12-
<Button type='submit' className='w-full md:w-[200px] mt-8 px-10'>
13-
Subscribe
14-
</Button>
15-
</a>
16-
</div>
17-
</div>
18-
);
4+
export default function Subscription() {
5+
const [subscribed, setSubscribed] = useState(false);
6+
7+
const handleSubscribe = (e) => {
8+
e.preventDefault();
9+
setSubscribed(true);
10+
};
11+
12+
return (
13+
<div className="flex flex-col items-center justify-center bg-[#12002b] p-10 rounded-lg shadow-lg text-white w-full max-w-2xl mx-auto">
14+
{!subscribed ? (
15+
<motion.div
16+
initial={{ opacity: 0, y: -20 }}
17+
animate={{ opacity: 1, y: 0 }}
18+
transition={{ duration: 0.5 }}
19+
className="w-full text-center"
20+
>
21+
<h3 className="text-2xl font-bold">Subscribe to our newsletter</h3>
22+
<p className="text-gray-300 mt-2">We respect your inbox. No spam, promise ✌️</p>
23+
24+
<form onSubmit={handleSubscribe} className="mt-5 flex flex-col sm:flex-row gap-3">
25+
<input type="text" placeholder="Your name" className="p-3 w-full rounded-md text-black" required />
26+
<input type="email" placeholder="Your email" className="p-3 w-full rounded-md text-black" required />
27+
<motion.button
28+
whileHover={{ scale: 1.05 }}
29+
whileTap={{ scale: 0.95 }}
30+
type="submit"
31+
className="bg-purple-500 hover:bg-purple-600 text-white font-bold px-6 py-3 rounded-md"
32+
>
33+
Subscribe
34+
</motion.button>
35+
</form>
36+
</motion.div>
37+
) : (
38+
<motion.div
39+
initial={{ opacity: 0, y: -20 }}
40+
animate={{ opacity: 1, y: 0 }}
41+
transition={{ duration: 0.5 }}
42+
className="text-center"
43+
>
44+
<h3 className="text-2xl font-bold">Thank you for subscribing!</h3>
45+
<p className="text-gray-300 mt-2">We respect your inbox. No spam, promise ✌️</p>
46+
</motion.div>
47+
)}
48+
</div>
49+
);
1950
}
20-
export default Subscription

0 commit comments

Comments
 (0)