diff --git a/src/App.css b/src/App.css index a8fd8a96ecd1583118b61838d907fadf6b6b7264..4d1241e7f319735924ae0ff47d4594d5c6b3212f 100644 --- a/src/App.css +++ b/src/App.css @@ -1,3 +1,6 @@ +@tailwind base; +@tailwind components; + body { display: flex; flex-direction: column; diff --git a/src/components/profile/SkillManagement.tsx b/src/components/profile/SkillManagement.tsx new file mode 100644 index 0000000000000000000000000000000000000000..5ed4080eb67786e317ea579d195c85523ef18bb3 --- /dev/null +++ b/src/components/profile/SkillManagement.tsx @@ -0,0 +1,94 @@ +import { useUserSkills } from "@/utils/context/SkillProvider"; +import { Skill } from "@/utils/validationSchema/skill"; +import { log } from "console"; +import React, { useEffect, useState } from "react"; +import { useQueryClient } from "react-query"; + +function SkillBit({ + onDelete, + skillName, +}: { + skillName: string; + onDelete: () => void; +}) { + return ( + <div + className="flex gap-2 bg-primary text-white px-4 py-2 rounded-md btn btn-neutral" + onClick={() => {}} + > + <p>{skillName}</p> + <button + className="px-2 py-0 bg-transparent" + onClick={(e) => { + e.stopPropagation(); + onDelete(); + }} + > + X + </button> + </div> + ); +} + +function SkillManagement() { + const queryClient = useQueryClient(); + const { userSkills, userSkillsStatus } = useUserSkills(); + const [selectedSkill, setSelectedSkill] = useState<Skill | undefined>( + undefined + ); + + useEffect(() => { + console.log(userSkills); + return () => {}; + }, [userSkills]); + + return ( + <div className="grid grid-cols-2 grid-rows-2 w-full"> + <div className="w-full flex flex-col items-center row-span-1 col-span-1 row-start-1 col-start-1"> + {userSkillsStatus === "success" && userSkills ? ( + <div className="flex flex-row flex-wrap gap-2"> + {userSkills.map(({ skillName }) => ( + <SkillBit + skillName={skillName} + key={skillName} + onDelete={() => { + queryClient.setQueryData<Skill[] | undefined>( + ["skills", "me"], + (oldSkills) => { + console.log("Old skills", oldSkills); + if (!oldSkills) { + return oldSkills; + } + return oldSkills.filter( + ({ skillName: thisSkill }) => thisSkill !== skillName + ); + } + ); + }} + /> + ))} + </div> + ) : ( + "Loading" + )} + </div> + <section className="w-full flex flex-col items-center lg:items-start row-span-1 row-start-2 col-span-1"> + <h3 className="text-xl font-bold self-start">Choose New Skills</h3> + </section> + <section className="bg-slate-600 box-border p-4 rounded-xl gap-4 w-full flex flex-col items-start row-span-2 row-start-1 col-start-2 col-span-1 h-full"> + {selectedSkill ? ( + <> + <h3 className="text-xl font-bold self-start"> + {selectedSkill.skillName} + </h3> + <p>{selectedSkill.description}</p> + </> + ) : ( + <p>Select a skill and see the details here</p> + )} + </section> + </div> + ); +} + +export default SkillManagement; diff --git a/src/pages/Profile.tsx b/src/pages/Profile.tsx index 1ec271d86c28260988d8ea4ffa7418620a08246c..d0d045b45498af938c1331e0062a32b73d3bcfd0 100644 --- a/src/pages/Profile.tsx +++ b/src/pages/Profile.tsx @@ -1,5 +1,6 @@ import AddSkillForm from "@/components/profile/AddSkillForm"; import ProfileForm from "@/components/profile/ProfileForm"; +import SkillManagement from "@/components/profile/SkillManagement"; import { logout } from "@/utils/api/auth"; import { useUser } from "@/utils/context/AuthProvider"; import SkillProvider from "@/utils/context/SkillProvider"; @@ -19,21 +20,21 @@ function Profile() { }); return ( - <div className="flex flex-col w-full max-w-xl justify-center items-center box-border py-4 lg:py-8 px-4 text-left gap-4"> + <div className="flex flex-col w-full justify-center items-start box-border py-4 lg:py-8 px-4 lg:px-8 text-left gap-4"> <SkillProvider> - <section className="w-full flex flex-col items-center"> + <section className="w-full max-w-xl flex flex-col items-center"> <h1 className="text-3xl font-bold self-start">Profile</h1> {user === undefined ? <p>Loading...</p> : <ProfileForm user={user} />} </section> - <section className="w-full flex flex-col items-center"> + <section className="w-full flex flex-col items-start lg:items-center"> <h2 className="text-2xl font-bold self-start">Skills</h2> - <section className="w-full flex flex-col items-center"> - <h3 className="text-xl font-bold self-start">Choose New Skills</h3> - </section> - <section className="w-full flex flex-col items-center"> - <h3 className="text-xl font-bold self-start">Add New Skills</h3> - <AddSkillForm /> - </section> + <div className="w-full flex flex-col items-start"> + <SkillManagement /> + <section className="w-full flex max-w-xl flex-col items-center"> + <h3 className="text-xl font-bold self-start">Add New Skills</h3> + <AddSkillForm /> + </section> + </div> </section> <section className="w-full flex flex-col items-center"> <h2 className="text-2xl font-bold self-start">Employer</h2> diff --git a/src/utils/api/skill.ts b/src/utils/api/skill.ts index 475f51cbcfe50263f3b554a60a1c3a1b7fc7a727..7faa58f69bf41856e1ad0f56c84188b31a99d1e3 100644 --- a/src/utils/api/skill.ts +++ b/src/utils/api/skill.ts @@ -1,10 +1,15 @@ import axios from "axios"; -import { Skill } from "../validationSchema/skill"; +import { Skill, SkillReturned } from "../validationSchema/skill"; import config from "../config"; import { header } from "."; export async function getSkills(): Promise<Skill[]> { - return (await axios.get(`${config.NODE_JS_API}/api/skill/`, header)).data; + return ( + (await axios.get(`${config.NODE_JS_API}/api/skill/`, header)) + .data as SkillReturned[] + ).map(({ skill_name, description }: SkillReturned) => { + return { skillName: skill_name, description }; + }); } export async function getUserSkills({ @@ -12,9 +17,13 @@ export async function getUserSkills({ }: { username: string; }): Promise<Skill[]> { + console.log("Getting user skills"); return ( - await axios.get(`${config.NODE_JS_API}/api/skill/${username}`, header) - ).data; + (await axios.get(`${config.NODE_JS_API}/api/skill/${username}`, header)) + .data as SkillReturned[] + ).map(({ skill_name, description }: SkillReturned) => { + return { skillName: skill_name, description }; + }); } export async function createSkill(payload: Skill): Promise<Skill> { diff --git a/src/utils/context/SkillProvider.tsx b/src/utils/context/SkillProvider.tsx index 5744ffcd42af9c38de19bf3c53e024f5125ec639..37f1c2f06e661183b8406336d09cdab787b8cde4 100644 --- a/src/utils/context/SkillProvider.tsx +++ b/src/utils/context/SkillProvider.tsx @@ -1,4 +1,4 @@ -import { ReactNode, createContext, useContext } from "react"; +import { ReactNode, createContext, useContext, useEffect } from "react"; import { QueryStatus, useQuery } from "react-query"; import { Skill } from "../validationSchema/skill"; import { getSkills, getUserSkills } from "../api/skill"; @@ -32,22 +32,35 @@ function SkillProvider({ children }: { children: ReactNode }) { retry: 3, } ); - const { status: userSkillsStatus, data: userSkills } = useQuery( - ["skills", "me"], - async () => { - if (status !== "loading" || user === undefined) { + const userSkillsQuery = useQuery({ + queryKey: ["skills", "me"], + queryFn: async () => { + console.log("Username in skill provider : ", user?.username); + console.log("User is : ", status); + if (status === "loading" || user === undefined) { return []; } + console.log("Getting actual user skills"); + return await getUserSkills({ username: user.username }); }, - { - cacheTime: 300000, - retry: 3, - } - ); + cacheTime: 300000, + retry: 3, + }); + + useEffect(() => { + console.log("Use effect : ", user); + // userSkillsQuery.refetch(); + }, [user]); + return ( <AllSkillsContext.Provider value={{ allSkills, allSkillsStatus }}> - <UserSkillsContext.Provider value={{ userSkills, userSkillsStatus }}> + <UserSkillsContext.Provider + value={{ + userSkills: userSkillsQuery.data, + userSkillsStatus: userSkillsQuery.status, + }} + > {children} </UserSkillsContext.Provider> </AllSkillsContext.Provider> diff --git a/src/utils/validationSchema/skill.ts b/src/utils/validationSchema/skill.ts index 87ba89ce749416190ad4af6fbf6ff5d0cc38d52b..67ad8233ee5d5e0e501f6cd4a9f2822cf327fc9f 100644 --- a/src/utils/validationSchema/skill.ts +++ b/src/utils/validationSchema/skill.ts @@ -13,4 +13,9 @@ export const skillSchema = z.object({ description: descriptionSchema, }); +export type SkillReturned = { + skill_name: string; + description: string; +}; + export type Skill = z.infer<typeof skillSchema>;