Skip to content

Commit

Permalink
Riyad/client dashboard (#252)
Browse files Browse the repository at this point in the history
* developing freelancer dashboard

* add new dashboard

* update the dashboard

* briefs search working

* swith profile on navbar

* 1. add applications page
2. add message page
3.add  ongoing page

* fix hovering issue

* functional applications count

* add myprojects page

* added filters for briefs container

* functional freelancer dashboard

* new bug fixes

* fixed tests with new changes on brief/apply

* approved brief fixes

* fixed redirect to freelancers/new

* fixed test

* 1.fix long descriptions
2. redirect to owner profile
3. redirect to brief
4. limit skill show to 4
5. handle chat click
6. remove search and filter button add redirect to brief

* 1. make chat click as popup

* fix client side error

* new comit

* 1. fix client side rendering issue

* 1. implemented the new client dashboard

* minor update

* fix client side error

* another fix

* 1. fix grant section in client dashboard
2. fix total earning in freelancer dashboard

* 1. fix typo
2. add user images
3. add backbutton to wallet page
4. add view all button to client dashboard

* 1. add item number to my projects
2. remove commented code
3 . add total spent

* making statics data to dynamics

* 1. fix myproject page
2. fix spent and earn section
3. adjust brief section to dynamic
4. adjust client card

* 1.add profile analytics
2.fix message name error

* text changes

* 1. project page is fixed

* add payment

* 1. fix default project tab

* 1. add welcome modal for new users
2. add freelancer hour per rate

* 1. minor fixes

* 1. fix percentage error

* 1. fix success rate to floor

* 1.Fix new  freelancer job success rate

---------

Co-authored-by: ssani7 <[email protected]>
  • Loading branch information
shakilahmedriyad and ssani7 authored Nov 9, 2023
1 parent 3a6f770 commit 5fc5086
Show file tree
Hide file tree
Showing 31 changed files with 1,064 additions and 358 deletions.
3 changes: 3 additions & 0 deletions public/Onboard/bank-note-01.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/Onboard/building-02.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/Onboard/globe-05.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/Onboard/hearts.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/Onboard/safe.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/Onboard/zap-square.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 9 additions & 3 deletions src/components/AreaGraph/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import dynamic from 'next/dynamic';

import { userAnalyticsType } from '@/pages/dashboard/new';

const Chart = dynamic(() => import('react-apexcharts'), {
ssr: false,
});

export default function AreaGrah() {
export default function AreaGrah({
userInfo,
}: {
userInfo: userAnalyticsType[];
}) {
const options = {
fill: {
colors: ['#3B27C1'],
Expand All @@ -21,14 +27,14 @@ export default function AreaGrah() {
show: false,
},
xaxis: {
categories: ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'],
categories: userInfo?.map((item) => item.label.substring(0, 3)),
},
};

const series = [
{
name: 'profile views',
data: [0, 0, 3, 5, 2, 6, 0],
data: userInfo?.map((item) => item.value),
},
];

Expand Down
40 changes: 29 additions & 11 deletions src/components/BriefComponent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import StarIcon from '@mui/icons-material/Star';
import { Rating } from '@mui/material';
import TimeAgo from 'javascript-time-ago';
import en from 'javascript-time-ago/locale/en.json';
import Image from 'next/image';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import {
AiOutlineCalendar,
AiOutlineClockCircle,
Expand All @@ -15,13 +14,28 @@ import { TbUsers } from 'react-icons/tb';
import { TfiEmail } from 'react-icons/tfi';
import { VscVerified } from 'react-icons/vsc';

import { Brief } from '@/model';

TimeAgo.addLocale(en);
const timeAgo = new TimeAgo('en-US');

export default function BriefComponent({ brief }: { brief: Brief }) {
export default function BriefComponent({ brief }: { brief: any }) {
const router = useRouter();
const [user_Activites, setUserActivites] = useState({
totalSpent: 0,
totalHire: 0,
activeHire: 0,
});
useEffect(() => {
let totalSpent = 0;
let totalHire = 0;
let activeHire = 0;
for (const project of brief.user_hire_history) {
if (project.project_status === 6) totalSpent += Number(project.cost);
if (project.project_status === 4 || project.status === 5) activeHire++;
if (project.project_status !== 0) totalHire++;
}
setUserActivites({ totalSpent, activeHire, totalHire });
}, [brief]);

return (
<div className='flex border-b hover:bg-imbue-light-purple-three cursor-pointer last:border-b-0'>
<div
Expand Down Expand Up @@ -119,17 +133,21 @@ export default function BriefComponent({ brief }: { brief: Brief }) {
<span className='text-imbue-purple mr-1.5'>
<HiOutlineCurrencyDollar size={20} />
</span>
$19k total spent
$
{user_Activites.totalSpent >= 1000
? Math.trunc(user_Activites.totalSpent / 1000) + 'k'
: user_Activites.totalSpent}{' '}
total spent
</p>
<p className='flex items-center'>
<span className='text-imbue-purple mr-2'>
<TbUsers size={18} />
</span>
59 hires,6 active
{user_Activites.totalHire} hires,{user_Activites.activeHire} active
</p>
</div>
<div className='text-xs pt-3 px-7 text-black'>
<Rating
{/* <Rating
className='text-base'
name='text-feedback'
value={4.68}
Expand All @@ -138,10 +156,10 @@ export default function BriefComponent({ brief }: { brief: Brief }) {
emptyIcon={
<StarIcon style={{ opacity: 0.55 }} fontSize='inherit' />
}
/>
/> */}
<div className='flex mt-1 justify-between'>
<p>4.68 of 40 reviews</p>
<p>Member since: Aug 17,2023</p>
{/* <p>4.68 of 40 reviews</p> */}
<p>Member since: {timeAgo.format(new Date(brief.joined))}</p>
</div>
</div>
</div>
Expand Down
38 changes: 31 additions & 7 deletions src/components/FreelancerCard/FreelancerCard.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
import Image from 'next/image';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { AiOutlineHeart } from 'react-icons/ai';
import { BiMessageRoundedDetail } from 'react-icons/bi';
import { HiOutlineTicket } from 'react-icons/hi';

import { Freelancer } from '@/model';

export default function FreelancerCard({
freelancer,
handleMessage,
}: {
freelancer: Freelancer;
freelancer: any;
handleMessage: any;
}) {
const router = useRouter();
const [freelancerSuccsRate, setFreelancerSuccessRate] = useState(0);

useEffect(() => {
let cancelProject = 0;
let completedProject = 0;
for (const project of freelancer.projects) {
if (project.status_id === 6) completedProject++;
if (project.status_id === 3) cancelProject++;
}
if (completedProject && cancelProject) {
const success =
(completedProject / (completedProject + cancelProject)) * 100;
setFreelancerSuccessRate(success);
}
}, [freelancer]);

return (
<div className='border min-w-[28.75rem] px-5 py-5 rounded-2xl '>
<div className='flex items-center gap-2'>
Expand Down Expand Up @@ -44,14 +59,23 @@ export default function FreelancerCard({
<div className='w-2 h-2 rounded-full bg-lime-900' />
</p>
</div>
{/* <div className='my-5 items-center flex justify-between'>
<div className='my-5 items-center flex justify-between'>
<p className='text-lg text-imbue-purple-dark'>
$50-$75 <span className='text-xs'>hr</span>
${freelancer.hour_per_rate.toFixed(2)}
<span className='text-xs'>hr</span>
</p>
<p className='text-xs'>
Job Success rate <span className='text-imbue-purple'>99.2%</span>
Job Success rate{' '}
{freelancerSuccsRate > 0 && (
<span className='text-imbue-purple'>
{Math.floor(freelancerSuccsRate)}%
</span>
)}
{freelancerSuccsRate === 0 && (
<span className='text-imbue-purple'>NA</span>
)}
</p>
</div> */}
</div>
<div className='flex mt-10 text-xs gap-5'>
{[1, 2, 3, 4].map(
(item: number, index: number) =>
Expand Down
36 changes: 24 additions & 12 deletions src/components/MessageComponent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import TimeAgo from 'javascript-time-ago';
import en from 'javascript-time-ago/locale/en.json';
import Image from 'next/image';
import { DefaultGenerics, FormatMessageResponse } from 'stream-chat';
import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { Channel, DefaultGenerics, User } from 'stream-chat';

import { RootState } from '@/redux/store/store';

TimeAgo.addLocale(en);

Expand All @@ -11,15 +15,22 @@ export default function MessageComponent({
handleMessageClick,
props,
}: {
props: FormatMessageResponse<DefaultGenerics>;
props: Channel<DefaultGenerics>;
handleMessageClick: any;
}) {
const { user } = useSelector((state: RootState) => state.userState);

const [targetUser, setTargetUser] = useState<User>();

useEffect(() => {
const key = Object.keys(props.state.members);
Number(props.state.members[key[0]]?.user_id) === user.id
? setTargetUser(props.state.members[key[1]]?.user)
: setTargetUser(props.state.members[key[0]]?.user);
}, [props.state.members, user.id]);

const handleClick = () => {
// router.push({
// pathname: `/dashboard/messages`,
// query: `chat=${props.cid?.split(':')[1]}`,
// });
handleMessageClick(props?.user?.id);
handleMessageClick(targetUser?.id);
};

return (
Expand All @@ -28,9 +39,9 @@ export default function MessageComponent({
className='flex items-center hover:bg-imbue-light-purple-three px-4 py-1 rounded-sm cursor-pointer text-black gap-5 text-sm'
>
<Image
className='w-14 h-14 mb-2 rounded-full'
className='w-14 h-14 object-cover mb-2 rounded-full'
src={
props?.user?.profile_photo ||
targetUser?.profile_photo ||
require('@/assets/images/profile-image.png')
}
width={40}
Expand All @@ -39,11 +50,12 @@ export default function MessageComponent({
/>
<div className='flex border-b w-full pb-2 justify-between'>
<div className=' space-y-1'>
<p>{props?.user?.name}</p>
<p className='text-text-aux-colour'>{props?.text}</p>
<p>{targetUser?.name}</p>
<p className='text-text-aux-colour'>{props?.lastMessage()?.text}</p>
</div>
<p className='min-w-fit text-text-aux-colour'>
{props?.created_at && timeAgo.format(new Date(props?.created_at))}
{props?.lastMessage()?.created_at &&
timeAgo.format(new Date(props?.lastMessage()?.created_at))}
</p>
</div>
</div>
Expand Down
31 changes: 7 additions & 24 deletions src/components/Navbar/NewNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ function NewNavbar() {
} = useSelector((state: RootState) => state.userState);
const dispatch = useDispatch<AppDispatch>();

const [expanded, setExpanded] = useState(false);

const handleClick = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
setOpenMenu(Boolean(event.currentTarget));
Expand Down Expand Up @@ -89,18 +87,12 @@ function NewNavbar() {
setup();
}, [dispatch, user?.username]);

const navigateToPage = (url: string) => {
if (user?.username) {
router.push(url);
} else {
setLoginModal(true);
}
};

const navPillclasses =
'text-imbue-purple-dark h-[3rem] bg-white rounded-[5.07319rem] !flex justify-center items-center px-5 hover:no-underline !text-[1rem] ';

const { profileView, setProfileMode } = useContext(AppContext) as AppContextType
const { profileView, setProfileMode } = useContext(
AppContext
) as AppContextType;

return (
<>
Expand Down Expand Up @@ -242,7 +234,6 @@ function NewNavbar() {
''
)}
<Link
onClick={() => setExpanded(false)}
className={`mx-1 hover:bg-imbue-lime-light text-xs lg:text-sm hidden lg:inline-block cursor-pointer ${navPillclasses} nav-item nav-item-2`}
href='/relay'
>
Expand All @@ -256,7 +247,6 @@ function NewNavbar() {
Wallet
</Link>
<div
onClick={() => setExpanded(false)}
className={`mx-1 relative group text-xs hover:bg-imbue-lime-light lg:text-sm hidden lg:inline-block cursor-pointer hover:underline ${navPillclasses}`}
>
<Image
Expand All @@ -277,8 +267,8 @@ function NewNavbar() {
<div
className='flex gap-2 items-center px-2 hover:bg-imbue-lime-light py-2 rounded-md '
onClick={() => {
setProfileMode('freelancer')
router.push('/dashboard')
setProfileMode('freelancer');
router.push('/dashboard');
}}
>
<div className='border p-1 rounded-xl'>
Expand All @@ -292,8 +282,8 @@ function NewNavbar() {
<div
className='flex gap-2 items-center px-2 hover:bg-imbue-lime-light py-2 rounded-md '
onClick={() => {
setProfileMode('client')
router.push('/dashboard')
setProfileMode('client');
router.push('/dashboard');
}}
>
<div className='border p-1 rounded-xl'>
Expand Down Expand Up @@ -420,13 +410,6 @@ function NewNavbar() {
/>
</Menu>
</header>
{/* <Login
visible={loginModal}
setVisible={(val: any) => {
setLoginModal(val);
}}
redirectUrl={router?.asPath}
/> */}
<LoginPopup
visible={loginModal}
setVisible={(val: any) => {
Expand Down
Loading

0 comments on commit 5fc5086

Please sign in to comment.