-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmainProfile.tsx
210 lines (202 loc) · 6.15 KB
/
mainProfile.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
"use client";
import { HeatMapDataForYear } from "@/app/(general)/[username]/page";
import {
Select,
SelectValue,
SelectContent,
SelectTrigger,
SelectItem,
} from "./ui/select";
import darkModeProfile from "@/public/bg-profile-dark.jpg";
import lightModeProfile from "@/public/bg-profile-light.jpg";
import Tooltip from "@uiw/react-tooltip";
import HeatMap from "@uiw/react-heat-map";
import React, { useEffect, useState, useTransition } from "react";
import { websiteBirthday } from "@/static/websiteBirthdayYear";
import Image from "next/image";
import { User } from "lucide-react";
import { Poppins } from "next/font/google";
import { Card, CardContent, CardHeader, CardTitle } from "./ui/card";
import { Progress } from "./ui/progress";
import { toast } from "./ui/use-toast";
import { usePathname, useRouter } from "next/navigation";
import { absoluteUrl } from "@/lib/utils";
import { Skeleton } from "./ui/skeleton";
import { getIndianTime } from "@/lib/dateTimeFun";
const poppins = Poppins({ weight: "300", subsets: ["latin"] });
type User = {
name: string;
photo: string | null;
description: string | null;
};
type Props = {
user: User;
heatMapData: HeatMapDataForYear;
heatMapYears: number;
totalSolvedQuestion: number;
};
export default function MainProfile({
user,
heatMapData,
heatMapYears,
totalSolvedQuestion,
}: Props) {
const [year, setYear] = useState(heatMapYears);
const [progress, setProgress] = useState(0);
const pathname = usePathname();
const router = useRouter();
const [isPending, startTransition] = useTransition();
useEffect(() => {
const timer = setTimeout(() => {
const solvedPer = parseInt(
((totalSolvedQuestion / 191) * 100).toFixed(2)
);
setProgress(solvedPer);
}, 500);
return () => clearTimeout(timer);
}, []);
useEffect(() => {
if (heatMapYears !== year) {
startTransition(() => {
router.push(absoluteUrl(`/${pathname}?year=${year}`));
});
}
}, [year]);
return (
<div className="max-w-[800px] mx-auto mt-5 ">
<ProfileBackground />
<ProfilePhoto photo={user.photo} />
<div className="translate-y-[-40px] ">
<p className="text-center font-semibold text-red-500">{`${user.name}`}</p>
<p
className={`text-center font-light max-w-[700px] mx-auto text-base ${poppins.className}`}
>
{user.description}
</p>
</div>
<Card className="mb-5 ">
<CardHeader className="text-center">
<CardTitle>Total Number Of Question In Striver Sheet</CardTitle>
</CardHeader>
<CardContent>
<Progress value={progress} />
<div className="flex justify-between font-bold">
<div>{`${totalSolvedQuestion}/191`}</div>
<div>{`${progress}%`}</div>
</div>
</CardContent>
</Card>
<div className="overflow-auto dark:bg-background border shadow-sm rounded-lg">
<div className="max-w-[200px] m-2 mx-auto">
<SelectYear year={year} selected={heatMapYears} setYear={setYear} />
</div>
<div className=" w-[800px] mx-auto">
{isPending ? (
<Skeleton className="h-[150px]" />
) : (
<HeatMap
value={heatMapData ?? []}
rectRender={(props, data) => {
if (!data.count) return <rect {...props} />;
return (
<Tooltip
key={props.key}
placement="top"
content={data.content}
>
<rect {...props} />
</Tooltip>
);
}}
className="w-[700px] mx-auto"
style={{
color: "red",
// @ts-ignore
"--rhm-rect": "#b9b9b9",
"--rhm-rect-active": "red",
}}
startDate={new Date(`${heatMapYears}/01/01`)}
/*
1-> 1st colro
2,3->2nd color
4,5->3rd color
6,192->4th color
*/
panelColors={{
2: "#e4b293",
4: "#d48462",
6: "#b91c1c",
193: "#450a0a",
}}
/>
)}
</div>
</div>
</div>
);
}
function ProfileBackground() {
return (
<div className="w-[100%] h-[20vh] overflow-hidden rounded-md ">
<Image
className="dark:block hidden h-[100%] w-[100%] object-none"
src={darkModeProfile}
alt="Background Photo"
/>
<Image
className=" dark:hidden h-[100%] w-[100%] object-none object-center"
src={lightModeProfile}
alt="Background Photo"
/>
</div>
);
}
function ProfilePhoto({ photo }: { photo: string | null }) {
return (
<div className="translate-y-[-50%] w-[100px] mx-auto">
{photo ? (
<Image
className="w-[100px] h-[100px] border-4 rounded-full border-red-500 "
src={photo}
alt="profile photo"
width={100}
height={100}
/>
) : (
<User className=" bg-white w-[100px] h-[100px] border-4 border-red-500 rounded-full text-red-500 dark:bg-background" />
)}
</div>
);
}
function SelectYear({
selected,
setYear,
year,
}: {
selected: number;
setYear: React.Dispatch<number>;
year: number;
}) {
const { year: todayYear } = getIndianTime();
const SelectedItems: React.ReactNode[] = [];
for (let year = websiteBirthday; year <= todayYear; year += 1) {
SelectedItems.push(
<SelectItem key={year} value={year.toString()}>
{year.toString()}
</SelectItem>
);
}
return (
<Select
value={selected.toString()}
onValueChange={(e) => {
setYear(parseInt(e.valueOf()));
}}
>
<SelectTrigger>
<SelectValue>{selected}</SelectValue>
</SelectTrigger>
<SelectContent>{SelectedItems}</SelectContent>
</Select>
);
}