Skip to content

Commit

Permalink
feat: user profile
Browse files Browse the repository at this point in the history
  • Loading branch information
d3george committed Oct 31, 2023
1 parent 0e2d352 commit 91e55b5
Show file tree
Hide file tree
Showing 8 changed files with 374 additions and 18 deletions.
Empty file added src/_mock/utils.js
Empty file.
17 changes: 0 additions & 17 deletions src/pages/management/user/profile.tsx

This file was deleted.

3 changes: 3 additions & 0 deletions src/pages/management/user/profile/connections-tab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function ConnectionsTab() {
return '4';
}
88 changes: 88 additions & 0 deletions src/pages/management/user/profile/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { CSSProperties, useState } from 'react';

import CoverImage from '@/assets/images/cover/cover_4.jpg';
import Card from '@/components/card';
import { Iconify } from '@/components/icon';
import { useUserInfo } from '@/store/userStore';
import { useThemeToken } from '@/theme/hooks';

import ConnectionsTab from './connections-tab';
import ProfileTab from './profile-tab';
import ProjectsTab from './projects-tab';
import TeamsTab from './teams-tab';

function UserProfile() {
const { avatar, username } = useUserInfo();
const { colorTextBase } = useThemeToken();
const [currentTabIndex, setcurrentTabIndex] = useState(0);

const bgStyle: CSSProperties = {
background: `linear-gradient(rgba(0, 75, 80, 0.8), rgba(0, 75, 80, 0.8)) center center / cover no-repeat, url(${CoverImage})`,
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center center',
};

const tabs = [
{
icon: <Iconify icon="solar:user-id-bold" size={24} className="mr-2" />,
title: 'Profile',
content: <ProfileTab />,
},
{
icon: <Iconify icon="mingcute:profile-fill" size={24} className="mr-2" />,
title: 'Teams',
content: <TeamsTab />,
},
{
icon: <Iconify icon="mingcute:profile-fill" size={24} className="mr-2" />,
title: 'Projects',
content: <ProjectsTab />,
},
{
icon: <Iconify icon="mingcute:profile-fill" size={24} className="mr-2" />,
title: 'Connections',
content: <ConnectionsTab />,
},
];

return (
<>
<Card className="relative mb-6 h-[290px] flex-col rounded-2xl !p-0">
<div style={bgStyle} className="h-full w-full">
<div className="flex flex-col items-center justify-center pt-12 md:absolute md:bottom-6 md:left-6 md:flex-row md:pt-0">
<img src={avatar} className="h-16 w-16 rounded-full md:h-32 md:w-32" alt="" />
<div
className="ml-6 mt-6 flex flex-col justify-center md:mt-0"
style={{ color: '#fff' }}
>
<span className="mb-2 text-2xl font-medium">{username}</span>
<span className="text-center opacity-50 md:text-left">TS FullStack</span>
</div>
</div>
</div>
<div className="z-10 min-h-[48px] w-full">
<div className="mx-6 flex h-full justify-center md:justify-end">
{tabs.map((tab, index) => (
<button
onClick={() => setcurrentTabIndex(index)}
key={tab.title}
type="button"
style={{
marginRight: index >= tabs.length - 1 ? '0px' : '40px',
opacity: index === currentTabIndex ? 1 : 0.5,
borderBottom: index === currentTabIndex ? `2px solid ${colorTextBase}` : '',
}}
>
{tab.icon}
{tab.title}
</button>
))}
</div>
</div>
</Card>
<div>{tabs[currentTabIndex].content}</div>
</>
);
}

export default UserProfile;
276 changes: 276 additions & 0 deletions src/pages/management/user/profile/profile-tab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
import { faker } from '@faker-js/faker';
import { Row, Col, Typography, Timeline } from 'antd';

import Card from '@/components/card';
import { IconButton, Iconify, SvgIcon } from '@/components/icon';
import { useUserInfo } from '@/store/userStore';
import ProTag from '@/theme/antd/components/tag';
import { useThemeToken } from '@/theme/hooks';

export default function ProfileTab() {
const { username } = useUserInfo();
const theme = useThemeToken();
const AboutItems = [
{ icon: <Iconify icon="fa-solid:user" size={18} />, label: 'Full Name', val: username },
{ icon: <Iconify icon="eos-icons:role-binding" size={18} />, label: 'Role', val: 'Developer' },
{ icon: <Iconify icon="tabler:location-filled" size={18} />, label: 'Country', val: 'USA' },
{ icon: <Iconify icon="ion:language" size={18} />, label: 'Language', val: 'English' },
{ icon: <Iconify icon="ph:phone-fill" size={18} />, label: 'Contact', val: '(123)456-7890' },
{ icon: <Iconify icon="ic:baseline-email" size={18} />, label: 'Email', val: username },
];

const ConnectionsItems = [
{
avatar: faker.image.avatarLegacy(),
name: faker.name.fullName(),
connections: `${faker.number.int(100)} Connections`,
connected: faker.datatype.boolean(),
},

{
avatar: faker.image.avatarLegacy(),
name: faker.name.fullName(),
connections: `${faker.number.int(100)} Connections`,
connected: faker.datatype.boolean(),
},

{
avatar: faker.image.avatarLegacy(),
name: faker.name.fullName(),
connections: `${faker.number.int(100)} Connections`,
connected: faker.datatype.boolean(),
},

{
avatar: faker.image.avatarLegacy(),
name: faker.name.fullName(),
connections: `${faker.number.int(100)} Connections`,
connected: faker.datatype.boolean(),
},

{
avatar: faker.image.avatarLegacy(),
name: faker.name.fullName(),
connections: `${faker.number.int(100)} Connections`,
connected: faker.datatype.boolean(),
},
];

const TeamItems = [
{
avatar: <Iconify icon="devicon:react" size={36} />,
name: 'React Developers',
members: `${faker.number.int(100)} Members`,
tag: <ProTag color="warning">Developer</ProTag>,
},
{
avatar: <Iconify icon="devicon:figma" size={36} />,
name: 'UI Designer',
members: `${faker.number.int(100)} Members`,
tag: <ProTag color="cyan">Designer</ProTag>,
},
{
avatar: <Iconify icon="logos:jest" size={36} />,
name: 'Test Team',
members: `${faker.number.int(100)} Members`,
tag: <ProTag color="success">Test</ProTag>,
},
{
avatar: <Iconify icon="logos:nestjs" size={36} />,
name: 'Nest.js Developers',
members: `${faker.number.int(100)} Members`,
tag: <ProTag color="warning">Developer</ProTag>,
},

{
avatar: <Iconify icon="logos:twitter" size={36} />,
name: 'Digital Marketing',
members: `${faker.number.int(100)} Members`,
tag: <ProTag>Marketing</ProTag>,
},
];

// const ProjectItems = [
// {
// avatar: faker.image.urlPlaceholder(),
// name: faker.company.name(),
// createAt: faker.date.past(),
// leader: faker.person.fullName(),
// },
// ];
return (
<>
<Row gutter={[16, 16]}>
<Col span={24} md={12} lg={8}>
<Card className="flex-col">
<div className="flex w-full flex-col">
<Typography.Title level={5}>About</Typography.Title>
<Typography.Text>{faker.lorem.paragraph()}</Typography.Text>

<div className="mt-2 flex flex-col gap-4">
{AboutItems.map((item) => (
<div className="flex">
<div className="mr-2">{item.icon}</div>
<div className="mr-2">{item.label}:</div>
<div className="opacity-50">{item.val}</div>
</div>
))}
</div>
</div>
</Card>
</Col>

<Col span={24} md={12} lg={16}>
<Card className="flex-col !items-start">
<Typography.Title level={5}>Activity Timeline</Typography.Title>
<Timeline
className="!mt-4 w-full"
items={[
{
color: theme.colorError,
children: (
<div className="flex flex-col">
<div className="flex items-center justify-between">
<Typography.Text strong>8 Invoices have been paid</Typography.Text>
<div className="opacity-50">Wednesday</div>
</div>
<Typography.Text type="secondary" className="text-xs">
Invoices have been paid to the company.
</Typography.Text>

<div className="mt-2 flex items-center gap-2">
<SvgIcon icon="ic_file_pdf" size={30} />
<span className="font-medium opacity-60">invoice.pdf</span>
</div>
</div>
),
},
{
color: theme.colorPrimaryActive,
children: (
<div className="flex flex-col">
<div className="flex items-center justify-between">
<Typography.Text strong>Create a new project for client 😎</Typography.Text>
<div className="opacity-50">April, 18</div>
</div>
<Typography.Text type="secondary" className="text-xs">
Invoices have been paid to the company.
</Typography.Text>
<div className="mt-2 flex items-center gap-2">
<img
alt=""
src={faker.image.avatarLegacy()}
className="h-8 w-8 rounded-full"
/>
<span className="font-medium opacity-60">
{faker.person.fullName()} (client)
</span>
</div>
</div>
),
},
{
color: theme.colorInfo,
children: (
<div className="flex flex-col">
<div className="flex items-center justify-between">
<Typography.Text strong>Order #37745 from September</Typography.Text>
<div className="opacity-50">January, 10</div>
</div>
<Typography.Text type="secondary" className="text-xs">
Invoices have been paid to the company.
</Typography.Text>
</div>
),
},
{
color: theme.colorWarning,
children: (
<div className="flex flex-col">
<div className="flex items-center justify-between">
<Typography.Text strong>Public Meeting</Typography.Text>
<div className="opacity-50">September, 30</div>
</div>
</div>
),
},
]}
/>
</Card>
</Col>
</Row>
<Row gutter={[16, 16]} className="mt-4">
<Col span={24} md={12}>
<Card className="flex-col !items-start">
<div className="flex w-full items-center justify-between">
<Typography.Title level={5}>Connections</Typography.Title>
<IconButton>
<Iconify icon="fontisto:more-v-a" />
</IconButton>
</div>
<div className="mt-2 flex w-full flex-col gap-4">
{ConnectionsItems.map((item) => (
<div className="flex">
<img alt="" src={item.avatar} className="h-10 w-10 flex-none rounded-full" />
<div className="ml-4 flex flex-1 flex-col">
<span className="font-semibold">{item.name}</span>
<span className="mt-1 text-xs opacity-50">{item.connections}</span>
</div>
<div
className="flex h-9 w-9 flex-none items-center justify-center rounded"
style={{
backgroundColor: item.connected ? theme.colorPrimaryText : 'transparent',
border: item.connected ? '' : `1px solid ${theme.colorPrimaryText}`,
}}
>
<Iconify
icon="tdesign:user"
color={item.connected ? '#fff' : theme.colorPrimaryText}
size={20}
/>
</div>
</div>
))}
</div>

<div
className="mt-4 w-full text-center text-lg"
style={{ color: theme.colorPrimaryText }}
>
View all connections
</div>
</Card>
</Col>
<Col span={24} md={12}>
<Card className="flex-col !items-start">
<div className="flex w-full items-center justify-between">
<Typography.Title level={5}>Teams</Typography.Title>
<IconButton>
<Iconify icon="fontisto:more-v-a" />
</IconButton>
</div>
<div className="mt-2 flex w-full flex-col gap-4">
{TeamItems.map((item) => (
<div className="flex">
{item.avatar}
<div className="ml-4 flex flex-1 flex-col">
<span className="font-semibold">{item.name}</span>
<span className="mt-1 text-xs opacity-50">{item.members}</span>
</div>
{item.tag}
</div>
))}
</div>

<div
className="mt-4 w-full text-center text-lg"
style={{ color: theme.colorPrimaryText }}
>
View all members
</div>
</Card>
</Col>
</Row>
</>
);
}
3 changes: 3 additions & 0 deletions src/pages/management/user/profile/projects-tab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function ProjectsTab() {
return '3';
}
3 changes: 3 additions & 0 deletions src/pages/management/user/profile/teams-tab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function TeamsTab() {
return '2';
}
Loading

0 comments on commit 91e55b5

Please sign in to comment.