Skip to content

Commit f920c4e

Browse files
committed
add hero section
1 parent 3fb7462 commit f920c4e

File tree

2 files changed

+157
-87
lines changed

2 files changed

+157
-87
lines changed

public/locales/en/components/home.json

+9-12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33
"name" : "React ChatBotify"
44
},
55

6+
"hero_section": {
7+
"title": "Easily customizable open-source chatbots",
8+
"heading.1": "A community-driven platform where developers and enthusiasts can browse, rate, and share custom themes and plugins.",
9+
"starText" : "Star",
10+
"forkText" : "Fork",
11+
"copyText" : "Copy",
12+
"links": ["View documentation", "Go to playground", "Browse themes", "Browse plugins"]
13+
},
14+
615
"features_section": {
716
"title": "What separates us from the rest",
817
"heading.1": "We envision a vibrant community where creativity and collaboration thrive, enabling chatbots to become more customizable and accessible for everyone.",
@@ -143,18 +152,6 @@
143152
"heading.3": "Easy Integration",
144153
"body_text.3": "Join a community of like-minded developers, share your own creations, and contribute to the growth of the platform."
145154
},
146-
"hero_section": {
147-
"title": "Easily customizable open-source chatbots",
148-
"name": "React ChatBotify",
149-
"body_text.1": "A community-driven platform where developers and enthusiasts can browse, rate, and share custom themes and plugins",
150-
"quicklinks": [
151-
"View documentation 📝",
152-
"Go to playground 🕹️",
153-
"Browse themes 🎨",
154-
"Browse plugins 🧩"],
155-
"usedByDevs" : "Already used by <strong>300+ developers</strong> around the world",
156-
"devsExperience" : "Read about their experiences"
157-
},
158155

159156
"history_section": {
160157
"title": "History and Background",

src/components/Home/HeroSection.tsx

+148-75
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,167 @@
11
import logo from "@/assets/images/logo.png";
2-
import { Avatar, AvatarGroup, Box, Link, Typography } from '@mui/material';
3-
import { useTranslation } from 'react-i18next';
2+
import { Box, Button, Link, Stack, Typography } from "@mui/material";
3+
import { ArrowRight } from "lucide-react";
4+
import { useCallback, useMemo } from "react";
5+
import { useTranslation } from "react-i18next";
6+
import { FaGithub } from "react-icons/fa";
47

5-
/**
6-
* Shows a broad overview of the chatbot when user lands on the home page.
7-
*/
88
const HeroSection = () => {
9-
// lazy loads translations
109
const { t } = useTranslation("components/home");
1110

11+
const links = useMemo(() => t("hero_section.links", { returnObjects: true }) as string[], [t]);
1212

13+
const handleCopy = useCallback(() => {
14+
navigator.clipboard.writeText("npm install react-chatbotify");
15+
}, []);
1316

14-
const LogoAndText = () => (
15-
<Box sx={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
16-
<Box component="img" src={logo} alt="Logo" sx={{ width: 32, height: 32, mx: 2 }} />
17-
<Typography variant="h6">
18-
{t("hero_section.name")}
19-
</Typography>
20-
</Box>
21-
);
17+
return (
18+
<Box sx={styles.container}>
19+
{/* Left Section */}
20+
<Box sx={styles.leftSection}>
21+
<Header appName={t("essentials.name")} />
22+
<Typography variant="h3" fontWeight={700} gutterBottom>
23+
{t("hero_section.title")}
24+
</Typography>
2225

23-
const QuickLinks = () => {
24-
const alllinks = t("hero_section.quicklinks", { returnObjects: true }) as string[];
25-
return (
26-
<Box sx={{ display: 'flex', gap: 5, flexWrap: 'wrap', alignSelf: 'start', alignItems: 'center', justifyContent: 'center' }}>
27-
{alllinks.map((link, index) => (
28-
<Link
29-
key={index}
30-
href="#"
31-
sx={{
32-
color: 'text.primary',
33-
":hover": { borderColor: 'primary.main' },
34-
textDecoration: 'none',
35-
fontWeight: 'bold',
36-
border: '2px solid white',
37-
borderColor: 'grey.800',
38-
padding: '12px 20px',
39-
borderRadius: 100
40-
}}
41-
>
42-
{link}
43-
</Link>
44-
))}
45-
</Box>
46-
);
47-
};
26+
<Typography variant="body1" color="text.secondary" paragraph>
27+
{t("hero_section.heading.1")}
28+
</Typography>
4829

49-
const avatars = [
50-
"https://randomuser.me/api/portraits/men/1.jpg",
51-
"https://randomuser.me/api/portraits/men/2.jpg",
52-
"https://randomuser.me/api/portraits/women/1.jpg",
53-
"https://randomuser.me/api/portraits/men/3.jpg",
54-
"https://randomuser.me/api/portraits/women/2.jpg",
55-
"https://randomuser.me/api/portraits/men/4.jpg",
56-
"https://randomuser.me/api/portraits/women/3.jpg",
57-
"https://randomuser.me/api/portraits/men/5.jpg",
58-
"https://randomuser.me/api/portraits/men/6.jpg",
59-
];
30+
<Stack direction={{ xs: "column", md: "row" }} alignItems={{ xs: "start", md: "center" }} spacing={4}>
31+
<NPMCommand handleCopy={handleCopy} copyText={t("hero_section.copyText")} />
32+
<GitHubStats starText={t("hero_section.starText")} forkText={t("hero_section.forkText")} />
33+
</Stack>
6034

61-
const UsedByDevs = () => (
62-
<Box textAlign="center" sx={{ backgroundColor: "#121212", p: 4, alignSelf: 'end', borderRadius: 2 }}>
63-
<AvatarGroup max={9} sx={{ justifyContent: "center" }}>
64-
{avatars.map((src, index) => (
65-
<Avatar style={{ border: '1px solid white' }} key={index} src={src} />
66-
))}
67-
</AvatarGroup>
68-
<Typography color="white" mt={2} dangerouslySetInnerHTML={ { __html: t("hero_section.usedByDevs") } } fontSize={18}>
69-
70-
</Typography>
71-
<Link href="#" color="primary" sx={{ display: "block", mt: 1 }}>
72-
{t("hero_section.devsExperience")}
73-
</Link>
35+
<Box sx={styles.linksContainer}>
36+
{links.map((link, index) => (
37+
<Link key={index} sx={styles.link}>
38+
{link} <ArrowRight size={16} />
39+
</Link>
40+
))}
41+
</Box>
42+
</Box>
43+
44+
{/* Right Section */}
45+
<FeaturePreview />
7446
</Box>
7547
);
48+
};
49+
50+
// Extracted Components
51+
const Header = ({appName}: {appName: string}) => (
52+
<Box sx={styles.header}>
53+
<Box component="img" src={logo} alt="Logo" sx={styles.logo} />
54+
<Typography fontWeight="bold" color="text.secondary">
55+
{appName}
56+
</Typography>
57+
</Box>
58+
);
59+
60+
const NPMCommand = ({ handleCopy, copyText }: { handleCopy: () => void; copyText: string }) => (
61+
<Box sx={styles.npmCommand}>
62+
<Typography variant="body2">npm install react-chatbotify</Typography>
63+
<Button variant="contained" onClick={handleCopy} sx={styles.copyButton}>
64+
{copyText}
65+
</Button>
66+
</Box>
67+
);
68+
69+
const GitHubStats = ({ starText, forkText }: { starText: string; forkText: string }) => {
70+
const stats = [
71+
{ text: starText, count: 250 },
72+
{ text: forkText, count: 138 },
73+
];
7674

7775
return (
78-
<Box sx={{ display: 'grid', gap: 4, justifyItems: 'center', minHeight: '90vh', py: '10px', gridTemplateColumns: '100%' }}>
79-
<Box sx={{ display: 'flex', mt: '50px', maxWidth: '700px', width: '90vw', height: 'fit-content', textAlign: 'center', flexDirection: 'column', alignItems: 'center', color: "text.muted", fontWeight: "strong", justifyItems: 'center' }}>
80-
<LogoAndText />
81-
<Typography variant="h2" sx={{ m: 3, color: "text.primary", lineHeight: 0.9, fontWeight: "bold" }}>
82-
{t("hero_section.title")}
83-
</Typography>
84-
<Typography variant="h6">
85-
{t("hero_section.body_text.1")}
86-
</Typography>
87-
</Box>
88-
<QuickLinks />
89-
<UsedByDevs />
76+
<Box sx={styles.statsContainer}>
77+
{stats.map((item, index) => (
78+
<Box key={index} sx={styles.statItem}>
79+
<FaGithub size={20} />
80+
<Typography variant="body2">
81+
{item.text} {item.count}
82+
</Typography>
83+
</Box>
84+
))}
9085
</Box>
9186
);
9287
};
9388

89+
const FeaturePreview = () => (
90+
<Box sx={styles.previewContainer}>
91+
<Typography color="text.secondary">Feature Preview</Typography>
92+
</Box>
93+
);
94+
95+
// Styles Object
96+
const styles = {
97+
container: {
98+
display: "flex",
99+
width: "100vw",
100+
alignItems: { xs: "center", md: "start" },
101+
flexDirection: { xs: "column", md: "row" },
102+
gap: 8,
103+
p: 7,
104+
pt: 10,
105+
},
106+
leftSection: {
107+
maxWidth: { xs: "auto", md: "60vw" },
108+
display: "flex",
109+
flexDirection: "column",
110+
gap: 2,
111+
},
112+
header: {
113+
display: "flex",
114+
alignItems: "center",
115+
gap: 2,
116+
},
117+
logo: {
118+
width: 32,
119+
height: 32,
120+
},
121+
npmCommand: {
122+
borderRadius: '16px',
123+
backgroundColor: "background.muted",
124+
pl: '16px',
125+
pr: '10px',
126+
py: '8px',
127+
display: "flex",
128+
alignItems: "center",
129+
gap: 2,
130+
},
131+
copyButton: {
132+
borderRadius: '10px',
133+
textTransform: "none",
134+
},
135+
statsContainer: {
136+
display: "flex",
137+
gap: 2,
138+
},
139+
statItem: {
140+
display: "flex",
141+
alignItems: "center",
142+
gap: 1,
143+
},
144+
linksContainer: {
145+
display: "flex",
146+
gap: 2,
147+
flexWrap: "wrap",
148+
},
149+
link: {
150+
display: "flex",
151+
alignItems: "center",
152+
gap: 1,
153+
},
154+
previewContainer: {
155+
display: "flex",
156+
alignItems: "center",
157+
justifyContent: "center",
158+
backgroundColor: "background.paper",
159+
borderRadius: 2,
160+
alignSelf: "center",
161+
height: 450,
162+
minWidth: 300,
163+
border: "1px solid blue",
164+
},
165+
};
166+
94167
export default HeroSection;

0 commit comments

Comments
 (0)