Skip to content

Commit d73769d

Browse files
authored
Merge pull request #346 from magshimim-next/dev
Update to v1.1.1
2 parents 083c116 + 9911f00 commit d73769d

File tree

15 files changed

+501
-297
lines changed

15 files changed

+501
-297
lines changed

cv_next/app/actions/users/getUser.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
getUserById,
88
getUserByUsername,
99
isCurrentFirstLogin,
10+
userIsAdmin,
1011
} from "@/server/api/users";
1112
import { Err, Ok } from "@/lib/utils";
1213
import logger, { logErrorWithTrace } from "@/server/base/logger";
@@ -129,3 +130,17 @@ export const isUserAuthor = async (
129130
const authorData = JSON.parse(JSON.stringify(cv.user_id));
130131
return Ok(userId.val == authorData.id);
131132
};
133+
134+
/**
135+
* Checks if the current user is an admin.
136+
* @returns {Promise<Result<void, string>>} A promise that resolves to a result which include empty ok if admin, and an error otherwise.
137+
*/
138+
export const isUserAdmin = async (): Promise<Result<void, string>> => {
139+
const adminCheckResult = await userIsAdmin();
140+
if (adminCheckResult.ok) {
141+
return Ok(adminCheckResult.val);
142+
} else {
143+
logErrorWithTrace(adminCheckResult);
144+
return Err("Couldn't check if the user is an admin");
145+
}
146+
};

cv_next/app/cv/[cvId]/components/commentSection/comment.tsx

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -72,34 +72,42 @@ const NewCommentBlock = ({
7272

7373
return commentOnCommentStatus ? (
7474
<div>
75-
<div
76-
style={{
77-
display: "flex",
78-
justifyContent: "space-between",
79-
alignItems: "center",
80-
}}
81-
>
82-
<textarea
83-
ref={inputRef}
84-
value={inputValue}
85-
onChange={(e) => {
86-
if (e.target.value.length < Definitions.MAX_COMMENT_SIZE + 1) {
87-
setInputValue(e.target.value);
88-
setShowError(false);
89-
} else {
90-
setShowError(true);
75+
<div className="flex items-end justify-between gap-2">
76+
<div className="flex w-full flex-col">
77+
<textarea
78+
ref={inputRef}
79+
value={inputValue}
80+
onChange={(e) => {
81+
if (e.target.value.length < Definitions.MAX_COMMENT_SIZE + 1) {
82+
setInputValue(e.target.value);
83+
setShowError(false);
84+
} else {
85+
setShowError(true);
86+
}
87+
}}
88+
onFocus={(e) =>
89+
e.currentTarget.setSelectionRange(
90+
e.currentTarget.value.length,
91+
e.currentTarget.value.length
92+
)
9193
}
92-
}}
93-
onFocus={(e) =>
94-
e.currentTarget.setSelectionRange(
95-
e.currentTarget.value.length,
96-
e.currentTarget.value.length
97-
)
98-
}
99-
onKeyDown={handleKeyDown}
100-
rows={2}
101-
className="mb-1 mt-1 block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
102-
/>
94+
onKeyDown={handleKeyDown}
95+
rows={2}
96+
className="mb-1 mt-1 block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
97+
/>
98+
<div className="px-1 text-right text-sm">
99+
<span
100+
className={`${
101+
inputValue.length >= Definitions.MAX_COMMENT_SIZE
102+
? "text-red-500"
103+
: "text-gray-500"
104+
}`}
105+
>
106+
{inputValue.length} / {Definitions.MAX_COMMENT_SIZE} characters
107+
</span>
108+
</div>
109+
</div>
110+
103111
<Tooltip id="Reply Icon" message="Reply">
104112
<RxPlus
105113
style={{ fontSize: "5vh", cursor: "pointer" }}
@@ -109,6 +117,7 @@ const NewCommentBlock = ({
109117
/>
110118
</Tooltip>
111119
</div>
120+
112121
<Alert
113122
display={showError ? "flex" : "none"}
114123
message={`Your comment can't be over ${Definitions.MAX_COMMENT_SIZE} characters long!`}

cv_next/app/cv/[cvId]/components/commentSection/commentForm.tsx

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -105,34 +105,44 @@ export default function CommentForm({ cv }: { cv: CvModel }) {
105105
return (
106106
<form className="mb-2" ref={formRef} action={formAction}>
107107
<div
108-
className="grid grid-cols-[90%_10%] rounded-lg rounded-t-lg border border-gray-200 bg-white py-2
109-
pl-4 pr-2 dark:border-gray-700 dark:bg-gray-800"
108+
className="grid grid-cols-[1fr_auto] items-end gap-x-2 rounded-lg border border-gray-200
109+
bg-white p-2 dark:border-gray-700 dark:bg-gray-800"
110110
>
111-
<label htmlFor={COMMENT_FIELD_NAME} className="sr-only">
112-
Your comment
113-
</label>
114-
<textarea
115-
id={COMMENT_FIELD_NAME}
116-
name={COMMENT_FIELD_NAME}
117-
onChange={handleChange}
118-
onKeyDown={handleKeyDown}
119-
value={text}
120-
rows={5}
121-
className={`
122-
row-span-2 mt-2 min-h-[2.5rem] w-full resize-none flex-col overflow-auto
123-
border-0 px-0 text-sm leading-5 text-gray-900
124-
focus:outline-none focus:ring-0 dark:bg-gray-800
125-
dark:text-white dark:placeholder-gray-400
126-
`}
127-
placeholder="Write a comment..."
128-
/>
111+
<div className="flex w-full flex-col">
112+
<label htmlFor={COMMENT_FIELD_NAME} className="sr-only">
113+
Your comment
114+
</label>
115+
<textarea
116+
id={COMMENT_FIELD_NAME}
117+
name={COMMENT_FIELD_NAME}
118+
onChange={handleChange}
119+
onKeyDown={handleKeyDown}
120+
value={text}
121+
rows={5}
122+
className="mt-2 w-full resize-none border-0 text-sm leading-5 text-gray-900
123+
focus:outline-none focus:ring-0 dark:bg-gray-800 dark:text-white
124+
dark:placeholder-gray-400"
125+
placeholder="Write a comment..."
126+
/>
127+
<div className="mt-1 text-right text-sm text-gray-500">
128+
<span
129+
className={`${
130+
text.length >= Definitions.MAX_COMMENT_SIZE
131+
? "text-red-500"
132+
: "text-gray-500"
133+
}`}
134+
>
135+
{text.length} / {Definitions.MAX_COMMENT_SIZE} characters
136+
</span>
137+
</div>
138+
</div>
129139

130140
<button
131141
type="submit"
132142
disabled={text.length > Definitions.MAX_COMMENT_SIZE}
133-
className="col-start-2 row-start-2 flex-col items-center rounded-lg bg-slate-50 px-4
134-
py-2.5 hover:bg-gray-300 focus:ring-4 focus:ring-gray-200 dark:bg-gray-800
135-
dark:text-white dark:hover:bg-gray-500/50 dark:focus:ring-gray-900"
143+
className="flex h-fit items-center justify-center rounded-lg bg-slate-50 px-4 py-2.5
144+
hover:bg-gray-300 focus:ring-4 focus:ring-gray-200 dark:bg-gray-800
145+
dark:text-white dark:hover:bg-gray-500/50 dark:focus:ring-gray-900"
136146
>
137147
<Tooltip id="Comment Icon" message="send">
138148
<RxPaperPlane />

cv_next/app/hall/page.tsx

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@ import Image from "next/image";
44
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
55
import { faLinkedinIn, faGithub } from "@fortawesome/free-brands-svg-icons";
66
import { ScrollToTop } from "@/components/ui/scrollToTop";
7-
import { External_Credits as contributors } from "@/lib/definitions";
7+
import { External_Credits as contributors, Team_Credits } from "@/lib/credits";
88
import useWindowSize from "@/hooks/useWindowSize";
99
import styles from "./styles.module.css";
10-
11-
const startsCount = 15;
10+
import FloatingStars from "./stars";
1211

1312
export default function Page() {
1413
const { scrollHeight, height } = useWindowSize();
@@ -18,11 +17,9 @@ export default function Page() {
1817
<title>Hall of Fame</title>
1918
<ul
2019
style={{ height: scrollHeight ? `${scrollHeight}px` : `${height}px` }}
21-
className={`${styles.crowns} absolute left-0 top-0 z-[-1] w-full overflow-hidden`}
20+
className={styles.starsContainer}
2221
>
23-
{Array.from({ length: startsCount }).map((_, index) => (
24-
<li key={index} className={styles["crowns li"]}></li>
25-
))}
22+
<FloatingStars />
2623
</ul>
2724
<div className="relative mx-auto h-full w-[700px] max-w-full xl:w-[1400px]">
2825
<ScrollToTop />
@@ -32,6 +29,64 @@ export default function Page() {
3229
>
3330
HALL OF FAME
3431
</h1>
32+
<h3 className="pb8 font-bold lg:text-lg">
33+
Our core team that is working hard to make this project a reality
34+
</h3>
35+
<h3 className="pb-8 text-base font-light text-muted-foreground lg:text-lg">
36+
Want to join us and help? Reach out to us in the community chat!
37+
</h3>
38+
<ul className="mb-8">
39+
<div className="flex h-auto w-full flex-row-reverse flex-wrap justify-center gap-3 self-center xl:flex">
40+
{Team_Credits.map((contributor) => (
41+
<div
42+
key={contributor.name}
43+
className={`${styles.card} relative m-[1vh] flex min-h-[25vh] w-[35vh] flex-col justify-between rounded-lg bg-primary-foreground p-4 text-center`}
44+
>
45+
<div
46+
className={`${styles["name-image"]} relative flex w-full items-center`}
47+
>
48+
<Image
49+
src={
50+
contributor.avatar_url ||
51+
"https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_1280.png"
52+
}
53+
width={50}
54+
height={50}
55+
className="mr-1 select-none"
56+
alt="Profile Picture"
57+
/>
58+
<h1 className="ml-4 max-w-full overflow-hidden break-words text-left text-base text-muted-foreground sm:text-lg lg:text-xl">
59+
{contributor.name}
60+
</h1>
61+
</div>
62+
<h4 className="mb-1 mt-4 select-none text-sm text-muted-foreground ">
63+
{contributor.title}
64+
</h4>
65+
<h3 className="mb-1 select-none text-base text-muted-foreground">
66+
{contributor.contribution}
67+
</h3>
68+
<div className="relative flex w-full items-center justify-end">
69+
{contributor.linkedIn && (
70+
<a href={contributor.linkedIn}>
71+
<FontAwesomeIcon
72+
icon={faLinkedinIn}
73+
className="mr-2 h-5 w-5"
74+
/>
75+
</a>
76+
)}
77+
{contributor.gitHub && (
78+
<a href={contributor.gitHub}>
79+
<FontAwesomeIcon
80+
icon={faGithub}
81+
className="ml-2 h-5 w-5"
82+
/>
83+
</a>
84+
)}
85+
</div>
86+
</div>
87+
))}
88+
</div>
89+
</ul>
3590
<h3 className="pb8 font-bold lg:text-lg">
3691
Awesome People Who Contributed to the Project
3792
</h3>

cv_next/app/hall/stars.module.css

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
.starsContainer {
2+
position: fixed;
3+
left: 0;
4+
right: 0;
5+
top: 0;
6+
bottom: 0;
7+
z-index: -1;
8+
overflow: hidden;
9+
pointer-events: none;
10+
}
11+
12+
.star {
13+
position: absolute;
14+
display: block;
15+
background: url(https://static.vecteezy.com/system/resources/previews/023/258/446/non_2x/a-star-with-transparent-background-sticker-illustration-free-png.png)
16+
no-repeat center/contain;
17+
filter: drop-shadow(2px 4px 10px gold);
18+
animation: floatUpward linear infinite;
19+
bottom: -100px;
20+
opacity: 0;
21+
}
22+
23+
@keyframes floatUpward {
24+
0% {
25+
transform: translateY(0) rotate(0deg);
26+
opacity: 0;
27+
}
28+
5% {
29+
opacity: 0.8;
30+
}
31+
95% {
32+
opacity: 0.8;
33+
}
34+
100% {
35+
transform: translateY(-120vh) rotate(720deg);
36+
opacity: 0;
37+
}
38+
}

cv_next/app/hall/stars.tsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { useState, useEffect, useMemo } from "react";
2+
import styles from "./stars.module.css";
3+
4+
const FloatingStars = ({ starCount = 15 }) => {
5+
const [isLoaded, setIsLoaded] = useState(false);
6+
7+
useEffect(() => {
8+
setIsLoaded(true);
9+
}, []);
10+
11+
const stars = useMemo(() => {
12+
return Array.from({ length: starCount }).map((_, index) => ({
13+
id: index,
14+
left: `${Math.random() * 90}%`,
15+
size: Math.floor(Math.random() * 70) + 30,
16+
delay: 2 + Math.random() * 12,
17+
duration: Math.random() * 10 + 15,
18+
}));
19+
}, [starCount]);
20+
21+
return (
22+
<div className={styles.starsContainer}>
23+
{isLoaded &&
24+
stars.map((star) => (
25+
<div
26+
key={star.id}
27+
className={styles.star}
28+
style={{
29+
left: star.left,
30+
width: `${star.size}px`,
31+
height: `${star.size}px`,
32+
animationDelay: `${star.delay}s`,
33+
animationDuration: `${star.duration}s`,
34+
}}
35+
/>
36+
))}
37+
</div>
38+
);
39+
};
40+
41+
export default FloatingStars;

0 commit comments

Comments
 (0)