Skip to content

Commit 24e1201

Browse files
authored
Merge pull request #53 from adel-gu/task/implement-about-page
Feat: Implement the about page
2 parents 5cabfac + 33a2fdc commit 24e1201

17 files changed

+533
-9
lines changed

src/assets/images/About/Hero-img.png

57.4 KB
Loading

src/components/About/Avatar.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { Link } from "react-router-dom"
2+
3+
type Props = {
4+
src?: string,
5+
alt?: string,
6+
isCounter?: boolean,
7+
total?: string,
8+
href?: string
9+
}
10+
11+
const Avatar: React.FC<Props> = ({src, alt, isCounter = false, total = "", href = ""}) => {
12+
13+
if (isCounter) return (
14+
<Link
15+
to={href}
16+
target="_blank"
17+
className={
18+
`
19+
h-10 w-10
20+
rounded-full
21+
ring-1 ring-slate-50
22+
flex justify-center items-center
23+
bg-slate-800
24+
hover:ring-secondary-500 transition-all
25+
`
26+
}
27+
>
28+
+{total}
29+
</Link>
30+
)
31+
32+
return (
33+
<Link to={href} target="_blank">
34+
<img
35+
src={src}
36+
alt={alt}
37+
className={
38+
`
39+
inline-block
40+
h-10 w-10
41+
rounded-full
42+
ring-1 ring-slate-50
43+
hover:ring-secondary-500 hover:ring-2 transition
44+
`
45+
}
46+
/>
47+
</Link>
48+
)
49+
}
50+
export default Avatar

src/components/About/AvatarsGroup.tsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { Link } from "react-router-dom"
2+
import Avatar from "./Avatar"
3+
import useFetchContributorsAvatars from "../../hooks/useFetchContributorsAvatar";
4+
5+
const TOTAL_AVATARS = 8
6+
7+
type Props = {
8+
repoUrl: string,
9+
repoName: string,
10+
repoTitle: string
11+
}
12+
13+
const AvatarsGroup: React.FC<Props> = ({ repoUrl, repoName, repoTitle }) => {
14+
const { contributors, total, loading, error } = useFetchContributorsAvatars(repoName);
15+
16+
// TODO: Add appropriate error message component, and a loading spinner
17+
if (loading) return <div>Loading...</div>;
18+
if (error) return <div>Error: {error.message}</div>;
19+
20+
return (
21+
<div className="flex flex-col items-center lg:items-start gap-2">
22+
<Link
23+
to={repoUrl}
24+
target="_blank"
25+
className="font-medium text-lg text-slate-500 underline"
26+
>
27+
{repoTitle}
28+
</Link>
29+
<div className="flex -space-x-4 overflow-hidden p-1">
30+
{
31+
contributors.slice(0,TOTAL_AVATARS).map((contributor) =>
32+
<Avatar
33+
key={contributor.login}
34+
src={contributor.avatar_url}
35+
alt={contributor.login}
36+
href={contributor.html_url}
37+
/>
38+
)
39+
}
40+
41+
{
42+
!(total < TOTAL_AVATARS) && <Avatar isCounter total={`${total}`} href={repoUrl}/>
43+
}
44+
</div>
45+
</div>
46+
)
47+
}
48+
export default AvatarsGroup

src/components/About/Card.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { ICard } from "../../interfaces/About"
2+
3+
const Card: React.FC<ICard> = ({ icon, heading, paragraph}) => {
4+
return (
5+
<div className={
6+
`
7+
max-w-sm p-6 bg-slate-900 border border-slate-500
8+
rounded-lg
9+
shadow
10+
text-slate-50 text-center
11+
space-y-4
12+
`
13+
}
14+
>
15+
<div className={
16+
`
17+
w-fit mx-auto
18+
rounded-full p-3
19+
flex justify-center items-center
20+
text-secondary-700 bg-secondary-900 bg-opacity-15
21+
`
22+
}
23+
>
24+
{icon}
25+
</div>
26+
<h5 className="mb-2 text-2xl font-bold tracking-tight">{heading}</h5>
27+
<p className="font-normal text-base lg:text-lg">{paragraph}</p>
28+
</div>
29+
)
30+
}
31+
export default Card

src/components/About/CardsSection.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { FeatureBenefitSet } from "../../interfaces/About"
2+
import Card from "./Card"
3+
4+
type Props = {
5+
content: FeatureBenefitSet
6+
}
7+
8+
const CardsSection: React.FC<Props> = ({content}) => {
9+
return (
10+
<div className="w-fit mx-auto text-center">
11+
<h2 className="font-semibold text-3xl mb-8">{content.title}</h2>
12+
<div className="flex flex-col gap-5 lg:flex-row">
13+
{
14+
content.cards.map(card => (
15+
<Card
16+
key={card.heading}
17+
icon={card.icon}
18+
heading={card.heading}
19+
paragraph={card.paragraph}
20+
/>
21+
))
22+
}
23+
</div>
24+
</div>
25+
)
26+
}
27+
export default CardsSection
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { Link } from "react-router-dom"
2+
import { Users } from "lucide-react"
3+
import AvatarsGroup from "./AvatarsGroup"
4+
5+
const REACT_CHATBOTIFY_GALLERY_URL = `
6+
https://github.com/tjtanjin/react-chatbotify-gallery-website/blob/main/docs/DeveloperGuide.md`
7+
const REACT_CHATBOTIFY_GALLERY = 'react-chatbotify-gallery-website'
8+
const REACT_CHATBOTIFY_GALLERY_TITLE = "Gallery Website"
9+
10+
const REACT_CHATBOTIFY_GALLERY_API_URL = `
11+
https://github.com/tjtanjin/react-chatbotify-gallery-api`
12+
const REACT_CHATBOTIFY_GALLERY_API = 'react-chatbotify-gallery-api'
13+
const REACT_CHATBOTIFY_GALLERY_API_TITLE = "Gallery API"
14+
15+
16+
const ContributorsSection = () => {
17+
return (
18+
<section className="">
19+
<div className="flex flex-col items-center text-center lg:flex-row lg:text-left lg:justify-between">
20+
<div className="space-y-4 flex flex-col items-center mb-6 lg:items-start">
21+
<Users className="text-secondary-700 size-12"/>
22+
<h2 className="font-semibold text-3xl">Contributors</h2>
23+
<p className="text-base max-w-[650px] lg:text-lg">
24+
We are grateful to the many developers who have contributed
25+
{" "}to the development of React ChatBotify Gallery,
26+
{" "}as well as authors of themes & plugins, to make the
27+
{" "}Gallery what it is today.
28+
{" "}Your involvement helps keep the platform dynamic and relevant.
29+
{" "}The list of contributors can be found on the project repositories
30+
</p>
31+
</div>
32+
<div className="space-y-3 lg:space-y-5 lg:pt-16">
33+
<AvatarsGroup
34+
repoUrl={REACT_CHATBOTIFY_GALLERY_URL}
35+
repoName={REACT_CHATBOTIFY_GALLERY}
36+
repoTitle={REACT_CHATBOTIFY_GALLERY_TITLE}
37+
/>
38+
<AvatarsGroup
39+
repoUrl={REACT_CHATBOTIFY_GALLERY_API_URL}
40+
repoName={REACT_CHATBOTIFY_GALLERY_API}
41+
repoTitle={REACT_CHATBOTIFY_GALLERY_API_TITLE}
42+
/>
43+
</div>
44+
</div>
45+
{/* How to Contribute */}
46+
<div className="space-y-4 flex flex-col items-center my-12 text-center lg:items-start lg:text-left">
47+
<h3 className="font-semibold text-2xl">How to Contribute</h3>
48+
<p className="text-base max-w-[650px] lg:text-lg">
49+
Want to contribute to React ChatBotify Gallery? We welcome
50+
{" "}your involvement! Whether you're submitting a new theme,
51+
{" "}improving existing plugins, or contributing code, your input
52+
{" "}helps us grow.
53+
{" "}<Link
54+
to={REACT_CHATBOTIFY_GALLERY_URL}
55+
target="_blank"
56+
className='text-secondary-500 hover:underline'
57+
>
58+
Visit our GitHub repositories
59+
</Link> for contribution
60+
{" "}guidelines and to get started.
61+
</p>
62+
</div>
63+
{/* Contact us */}
64+
<div className="space-y-4 flex flex-col items-center pb-12 text-center lg:items-start lg:text-left">
65+
<h3 className="font-semibold text-2xl">Contact us</h3>
66+
<p className="text-base max-w-[650px] lg:text-lg">
67+
Have questions or want to get in touch?
68+
{" "}Reach out to us via
69+
{" "}<Link
70+
to={REACT_CHATBOTIFY_GALLERY}
71+
target="_blank"
72+
className='text-secondary-500 hover:underline'
73+
>
74+
Discord
75+
</Link>
76+
{" "}and stay in touch with the latest updates and community news!
77+
78+
</p>
79+
</div>
80+
81+
</section>
82+
)
83+
}
84+
export default ContributorsSection
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { Blocks, Settings, Share2, Timer, TrendingUp, UnfoldHorizontal } from "lucide-react"
2+
import CardsSection from "./CardsSection"
3+
4+
const features = {
5+
title: 'Key Features',
6+
cards: [
7+
{
8+
icon: <UnfoldHorizontal />,
9+
heading: 'Extensive Library',
10+
paragraph: 'Access a growing collection of themes and plugins specifically designed for React ChatBotify.'
11+
},
12+
{
13+
icon: <TrendingUp />,
14+
heading: 'Community Ratings',
15+
paragraph: 'Browse through user ratings to find the most popular and reliable options.'
16+
},
17+
{
18+
icon: <Share2 />,
19+
heading: 'Collaborative Community',
20+
paragraph: 'Download and integrate themes and plugins with your chatbot effortlessly.'
21+
},
22+
]
23+
}
24+
25+
const benefits = {
26+
title: 'Benefits',
27+
cards: [
28+
{
29+
icon: <Timer />,
30+
heading: 'Save Time',
31+
paragraph: 'Utilize pre-built themes and plugins to accelerate your development process.'
32+
},
33+
{
34+
icon: <Settings />,
35+
heading: 'Enhance Functionality',
36+
paragraph: 'Easily add new features and improve the user experience of your chatbot.'
37+
},
38+
{
39+
icon: <Blocks />,
40+
heading: 'Easy Integration',
41+
paragraph: `
42+
Join a community of like-minded developers,
43+
share your own creations,
44+
and contribute to the growth of the platform.
45+
`
46+
},
47+
]
48+
}
49+
50+
51+
const FeaturesAndBenefitsSection = () => {
52+
return (
53+
<section>
54+
<CardsSection content={features}/>
55+
<div className="my-32"/>
56+
<CardsSection content={benefits}/>
57+
</section>
58+
)
59+
}
60+
export default FeaturesAndBenefitsSection

src/components/About/HeroAbout.tsx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { Link } from 'react-router-dom'
2+
import HeroImg from '../../assets/images/About/Hero-img.png'
3+
4+
const REACT_CHATBOTIFY_URL = "https://www.npmjs.com/package/react-chatbotify";
5+
6+
const HeroAbout = () => {
7+
return (
8+
<section className='flex flex-col justify-centre items-center pt-32 gap-12 lg:flex-row lg:justify-between'>
9+
<div className='flex-1 space-y-6 text-center lg:text-left'>
10+
<h1 className='font-extrabold text-2xl lg:text-5xl'>
11+
About React ChatBotify Gallery
12+
</h1>
13+
<p className='space-y-4 text-base lg:text-lg max-w-[500px]'>
14+
<span className='block'>
15+
A community-driven platform where developers
16+
{' '} and enthusiasts can browse, rate,
17+
{' '} and share custom themes and plugins for
18+
{' '}
19+
<Link
20+
to={REACT_CHATBOTIFY_URL}
21+
className='text-secondary-500 hover:underline'
22+
target="_blank"
23+
>
24+
React ChatBotify
25+
</Link>.
26+
</span>
27+
<span className='block'>
28+
Our gallery offers a wide range of works contributed by users worldwide,
29+
{' '} making it easier than ever to enhance your chatbot's design and functionality.
30+
</span>
31+
</p>
32+
</div>
33+
<div className='relative flex-1'>
34+
<img src={HeroImg} className='size-3/4 mx-auto relative z-10 aspect-square lg:mx-0 lg:ml-auto'/>
35+
<div
36+
className={
37+
`
38+
absolute size-[55%]
39+
bg-gradient-to-r from-secondary-900 to-primary-500
40+
-rotate-45
41+
rounded-full
42+
z-0 top-[55%] left-[60%]
43+
-translate-x-[50%] -translate-y-[50%]
44+
blur-[200px]
45+
`
46+
}
47+
/>
48+
</div>
49+
</section>
50+
)
51+
}
52+
export default HeroAbout
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Hourglass } from "lucide-react"
2+
3+
const HistorySection = () => {
4+
return (
5+
<section className="flex flex-col items-center text-center gap-4">
6+
<Hourglass className="text-secondary-700 size-12 rotate-12"/>
7+
<h2 className="font-semibold text-3xl">History and Background</h2>
8+
<p className="text-base lg:text-lg max-w-[650px]">
9+
React ChatBotify Gallery started as a project
10+
{" "}to complement the v2 release of React ChatBotify in 2024.
11+
{" "}It was born out of the need for a centralized repository
12+
{" "}of chatbot themes and plugins.
13+
{" "}As more developers began contributing,
14+
{" "}the platform quickly grew into a vibrant community,
15+
{" "}constantly evolving to meet the needs of its users.
16+
</p>
17+
</section>
18+
)
19+
}
20+
export default HistorySection

0 commit comments

Comments
 (0)