Skip to content

Commit ff9cafd

Browse files
committed
feat: new profile page ui
1 parent d1e37a3 commit ff9cafd

File tree

13 files changed

+305
-76
lines changed

13 files changed

+305
-76
lines changed

package-lock.json

Lines changed: 26 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,16 @@
2323
"@typescript-eslint/eslint-plugin": "^5.60.1",
2424
"@vitejs/plugin-react": "^4.2.1",
2525
"file-saver": "^2.0.5",
26+
"i18next": "^23.15.2",
27+
"i18next-browser-languagedetector": "^8.0.0",
28+
"i18next-http-backend": "^2.6.2",
2629
"jszip": "^3.10.1",
2730
"lucide-react": "^0.376.0",
2831
"prop-types": "^15.8.1",
2932
"react": "^18.2.0",
3033
"react-chatbotify": "^2.0.0-beta.3",
3134
"react-dom": "^18.2.0",
35+
"react-i18next": "^15.0.2",
3236
"react-loading-skeleton": "^3.4.0",
3337
"react-router-dom": "^6.2.2",
3438
"uuid": "^9.0.1",

src/components/profile/Themecard.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { GenericItemCardProps } from "../../interfaces/profile"
2+
3+
export const ThemeCard: React.FC<GenericItemCardProps> = ({ mode, themeImg, name, description }) => {
4+
return (
5+
<div className="flex gap-3 w-full h-fit flex-row">
6+
<img className="w-20 rounded-lg" src={themeImg} />
7+
<div className="flex flex-col w-full relative gap-3">
8+
<h1 className="font-extrabold text-xl">{name}</h1>
9+
<p className="text-primary-mutedForeground text-sm block ">{description}</p>
10+
<div className="flex absolute bottom-0 bg-primary-darkForeground flex-row gap-2">
11+
<a className=" cursor-pointer text-sm text-blue-500 ">View Theme</a>
12+
{mode == 1 && <a className="cursor-pointer text-sm text-red-500">Remove favourite</a>}
13+
</div>
14+
</div>
15+
</div>
16+
)
17+
}

src/components/profile/emptySVG.jsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export default function EmptySVG (){
2+
return (
3+
<svg width="140" height="139" viewBox="0 0 140 139" fill="none" xmlns="http://www.w3.org/2000/svg">
4+
<path d="M20.813 64.7656H115.636V137.69C115.636 137.838 115.577 137.981 115.472 138.086C115.367 138.191 115.224 138.25 115.076 138.25H21.373C21.2245 138.25 21.082 138.191 20.977 138.086C20.872 137.981 20.813 137.838 20.813 137.69V64.7656Z" fill="#93C5FD"/>
5+
<path d="M91.8476 36.1914H47.7572L20.813 64.7685H115.636L91.8476 36.1914Z" fill="#3B82F6"/>
6+
<path d="M29.7941 24.7578L47.7569 36.1888L20.8127 64.7659L0.400391 49.2525L29.7941 24.7578Z" fill="#60A5FA"/>
7+
<path d="M109.81 24.7578L91.8472 36.1888L115.635 64.7659L139.204 49.2525L109.81 24.7578Z" fill="#60A5FA"/>
8+
<path d="M59.3405 25.3417C59.8473 25.1014 60.2417 24.6745 60.4412 24.1501C60.6406 23.6258 60.6297 23.0447 60.4107 22.5282L52.33 3.47386C52.2156 3.20396 52.0477 2.96 51.8366 2.75663C51.6254 2.55327 51.3753 2.39471 51.1013 2.29049C50.8273 2.18626 50.535 2.13853 50.2421 2.15015C49.9492 2.16177 49.6616 2.23251 49.3967 2.35811L47.8399 3.09631C47.5751 3.22191 47.3383 3.39977 47.1439 3.61921C46.9495 3.83865 46.8015 4.09513 46.7088 4.37324C46.6161 4.65134 46.5805 4.94532 46.6043 5.23751C46.6281 5.5297 46.7108 5.81406 46.8473 6.07349L56.4847 24.3895C56.7459 24.886 57.1889 25.2623 57.7211 25.4398C58.2533 25.6172 58.8335 25.5821 59.3405 25.3417Z" fill="#3B82F6"/>
9+
<path d="M69.4715 23.4986C69.8383 23.4724 70.1809 23.3055 70.4276 23.0328C70.6743 22.76 70.8061 22.4025 70.7954 22.0348L70.3962 8.46982C70.3906 8.27767 70.3461 8.08866 70.2655 7.91413C70.185 7.73961 70.0699 7.58317 69.9274 7.45424C69.7848 7.32531 69.6176 7.22653 69.4359 7.16386C69.2542 7.10118 69.0616 7.0759 68.8699 7.08952L67.7429 7.16983C67.5512 7.18348 67.3642 7.23573 67.1933 7.32345C67.0223 7.41118 66.8708 7.53256 66.748 7.68031C66.6251 7.82806 66.5334 7.99912 66.4783 8.18322C66.4232 8.36732 66.4059 8.56065 66.4274 8.75161L67.9536 22.2364C67.9949 22.602 68.1759 22.9375 68.4588 23.1727C68.7416 23.4079 69.1045 23.5247 69.4715 23.4986Z" fill="#3B82F6"/>
10+
<path d="M77.2925 28.5099C78.3016 29.0934 79.7182 28.558 80.5039 27.2961L94.4552 4.89017C95.2886 3.55166 95.0911 1.92027 94.0209 1.30147L92.529 0.439072C91.4587 -0.17984 89.9463 0.462814 89.202 1.85284L76.7425 25.1211C76.0408 26.4316 76.2834 27.9264 77.2925 28.5099Z" fill="#3B82F6"/>
11+
</svg>
12+
13+
)
14+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { UserData } from '../../interfaces/UserData'
2+
3+
4+
export default function ProfileInfo ({userInfo} : {userInfo: UserData | null} ) {
5+
return (
6+
<div className="rounded-xl w-[95vw] grid gap-8
7+
text-primary-mutedForeground self-center my-5 p-10 bg-primary-darkForeground ">
8+
<h2 className="font-extrabold text-xl text-primary-white">Profile information</h2>
9+
<ProfileCard {...userInfo} />
10+
<OtherInfo {...userInfo} />
11+
</div>
12+
)
13+
14+
}
15+
16+
const ProfileCard: React.FC<UserData | any> = ({name, handle, avatarUrl, status}) => {
17+
return(
18+
<div className="grid gap-5 justify-start self-center">
19+
<div className="grid p-1 w-fit grid-flow-col gap-3 h-fit">
20+
<img className="w-11 rounded-3xl h-11" src={avatarUrl}></img>
21+
<div >
22+
<h3 className="font-extrabold">{name}</h3>
23+
<p>{handle}</p>
24+
</div>
25+
</div>
26+
<p className="text-sm">{status}</p>
27+
</div>
28+
)
29+
}
30+
31+
const OtherInfo: React.FC<UserData | any> = ({joindate, location, role}) => {
32+
return (
33+
<div className="flex flex-row gap-8">
34+
<div className="grid text-sm items-start gap-1">
35+
<h5 className={`font-extrabold ${!location ? 'text-primary-disabledForeground' : ''}`}>
36+
Location
37+
</h5>
38+
<h5>{location}</h5>
39+
</div>
40+
<div className="grid text-sm items-start gap-1">
41+
<h5 className={`font-extrabold ${!joindate ? 'text-primary-disabledForeground' : ''}`}>
42+
Joined React Chatbotify
43+
</h5>
44+
<h5>{joindate}</h5>
45+
</div>
46+
<div className="grid text-sm items-start gap-1">
47+
<h5 className={`font-extrabold ${!role ? 'text-primary-disabledForeground' : ''}`}>
48+
Community role
49+
</h5>
50+
<h5>{role}</h5>
51+
</div>
52+
</div>
53+
)
54+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import EmptySVG from "./emptySVG";
2+
import { useState } from "react";
3+
import { config } from "../../configs/profileconfig";
4+
import { ItemsIterator, PropTypes } from "../../interfaces/profile";
5+
6+
7+
8+
9+
10+
export default function ProfileMaterialContainer(Props: PropTypes) {
11+
const { type, items, loading } = Props
12+
let MainContent : any = EmptyMaterialPLaceholder
13+
if (loading) {
14+
MainContent = LoadingPlaceholder
15+
} else if (items.length > 0) {
16+
MainContent = ItemsHandler
17+
}
18+
19+
const mode = useState(1)[0] //I had to make it like this temporarily, fixing soon
20+
21+
22+
23+
return (
24+
<div className="rounded-xl w-[95vw] grid gap-8 text-primary-white self-center my-5
25+
p-10 bg-primary-darkForeground">
26+
<div className="">
27+
<h2 className="font-extrabold float-left text-xl ">{config[type].mainHeading}</h2>
28+
<div className="float-right">toggle here</div>
29+
</div>
30+
<MainContent {...Props} mode={mode} config={config[type]} />
31+
{ !loading && items.length > 0 && <a href={config[type].allUrl}
32+
className="underline justify-self-center cursor-pointer text-primary-mutedForeground">see all</a>
33+
} </div>
34+
)
35+
}
36+
37+
38+
const EmptyMaterialPLaceholder = ({ mode, config, }: { type: string, mode: number, config: any }) => {
39+
return (
40+
41+
<div className="w-fit grid gap-9 p-3 justify-items-center items-center justify-self-center self-center">
42+
<EmptySVG />
43+
<div className="gap-2 grid justify-items-center">
44+
<h1 className="font-extrabold">{config.emptyState.subHeading[mode]}</h1>
45+
<p className="text-primary-mutedForeground">{config.emptyState.subText}</p>
46+
</div>
47+
<div className="grid grid-flow-col gap-3">
48+
<button className="bg-slate-400">
49+
{config.emptyState.buttons.secondary}
50+
</button>
51+
<button className="bg-slate-400">
52+
{config.emptyState.buttons.primary}
53+
</button>
54+
</div>
55+
</div>
56+
)
57+
}
58+
59+
const LoadingPlaceholder = () => ('loading...')
60+
61+
62+
const ItemsHandler: React.FC<ItemsIterator> = ({ items, mode, config }) => {
63+
const ItemCard = config.elements.ItemCard
64+
return (
65+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-8">
66+
{
67+
items.map((item : any) => (
68+
<ItemCard {...item} mode={mode} />
69+
))
70+
}
71+
</div>
72+
)
73+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
export default function ProfileSettings () {
2+
return (
3+
<div className="rounded-xl w-[95vw] grid gap-8 text-primary-white
4+
self-center my-5 p-10 bg-primary-darkForeground">
5+
<h2 className="font-extrabold text-xl ">Profile settings</h2>
6+
<div className="flex flex-row gap-14 flex-wrap">
7+
<div className="grid grid-flow-row gap-3">
8+
<h3 className="text-sm font-extrabold">Language</h3>
9+
<Select >
10+
<option>English</option>
11+
</Select>
12+
</div>
13+
<div className="grid grid-flow-row gap-3">
14+
<h3 className="text-sm font-extrabold">Color theme</h3>
15+
<Select>
16+
<option>Browser default</option>
17+
<option>Dark</option>
18+
<option>Light</option>
19+
</Select>
20+
</div>
21+
</div>
22+
</div>
23+
)
24+
}
25+
26+
const Select = ({children, onchangefunc} : any) => (
27+
<select onChange={onchangefunc} className="bg-transparent border-accent-500 border-2 rounded-lg px-5 py-1">
28+
{children}
29+
</select>
30+
)
31+
32+
//im writing type to any temporarily, until we use a cmpnt library

src/configs/profileconfig.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { ThemeCard } from "../components/profile/Themecard";
2+
import { Config } from "../interfaces/profile";
3+
4+
export const config: Config = {
5+
themes: {
6+
allUrl: '/themes',
7+
mainHeading: 'Themes',
8+
emptyState: {
9+
subHeading: {
10+
1: 'No favourite themes yet',
11+
0: 'No personal themes yet'
12+
},
13+
subtext: 'Browse theme selection or create your own',
14+
buttons: {
15+
primary: 'Build your own theme',
16+
secondary: 'Browse Themes'
17+
}
18+
},
19+
elements: {
20+
ItemCard: ThemeCard
21+
}
22+
},
23+
plugins: {
24+
25+
}
26+
}

src/constants/dummyData.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export const profileDummy = {
2+
name: 'Hunain Ahmed',
3+
handle: 'hunxjunedo',
4+
avatarUrl: 'https://avatars.githubusercontent.com/u/89797440?v=4',
5+
status: 'lorem ipsum dolor sit amet',
6+
location: 'Karachi, Pakistan',
7+
joindate: '24 feb, 2024',
8+
role: 'devrel',
9+
10+
}

src/interfaces/UserData.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ export interface UserData {
1414
profileUrl: string;
1515
provider: string;
1616
providerUserId: string;
17+
joindate?: string;
1718
}

0 commit comments

Comments
 (0)