diff --git a/devsoc24-portal-fe/src/app/home/page.tsx b/devsoc24-portal-fe/src/app/home/page.tsx new file mode 100644 index 0000000..4e8b7c1 --- /dev/null +++ b/devsoc24-portal-fe/src/app/home/page.tsx @@ -0,0 +1,350 @@ +"use client"; +import Image from "next/image"; +import { useRouter } from "next/navigation"; +import { useEffect, useState } from "react"; +import Logo from "@/components/logo"; +import Dashtitle from "@/assets/images/titleDashboard.svg"; +import CustomCard from "@/components/customCard"; +import TeamCard from "@/components/teamCard"; +import axios, { AxiosError, type AxiosResponse } from "axios"; +import { + useIdeaStore, + useLeaderStore, + useTeamDataStore, + useTeamStore, + useUserStore, +} from "@/store/store"; +import Loading from "../loading"; +import TrackComponent from "@/components/track/TrackComponent"; +import toast, { Toaster } from "react-hot-toast"; +import { refresh, type userProps } from "@/interfaces"; +import { type APIResponse } from "@/schemas/api"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { Button } from "@/components/ui/button"; +import { User } from "lucide-react"; +import ToastContainer from "@/components/ToastContainer"; +import Link from "next/link"; +import TimelineComponent from "@/components/timeline/timelineComponent"; + +interface ideaProps { + message: string; + status: boolean; + data?: { + title: string; + description: string; + track: string; + github_link: string; + figma_link: string; + others: string; + }; +} + +interface teamProps { + data: { + token_expired?: boolean; + }; + message: string; + status: string; +} + +export default function HomePage() { + const router = useRouter(); + const { idea, setIdea } = useIdeaStore(); + const { team, setTeam } = useTeamStore(); + const { user, setUser } = useUserStore(); + const [getIdea, SetIdea] = useState(""); + const { teamData, setTeamData } = useTeamDataStore(); + const { isLeader, setIsLeader } = useLeaderStore(); + const logout = async () => { + try { + const response = await axios.post( + `${process.env.NEXT_PUBLIC_API_URL}/logout`, + { + nallaData: "", + }, + { + withCredentials: true, + }, + ); + localStorage.clear(); + void router.push("/"); + } catch (e) { + if (axios.isAxiosError(e)) { + switch (e.response?.status) { + case 401: + await refresh(); + console.log("401"); + break; + default: + console.log(e); + break; + } + } + } + }; + + const handleLogout = async () => { + void toast.promise(logout(), { + loading: "Logging out...", + success: "Logged out successfully!", + error: "Something went wrong!", + }); + void router.push("/"); + }; + + const fetchData = async () => { + try { + const response: AxiosResponse = await axios.get( + `${process.env.NEXT_PUBLIC_API_URL}/user/me`, + { + withCredentials: true, + }, + ); + console.log(response.data.data.is_leader); + setIsLeader(response.data.data.is_leader); + console.log(isLeader); + } catch (e) { + if (axios.isAxiosError(e)) { + switch (e.response?.status) { + case 401: + void router.push("/"); + break; + case 404: + console.log("no team"); + break; + case 409: + console.log("Not in team"); + break; + default: + console.log(e); + break; + } + } + } + }; + + const fetchTeam = async () => { + try { + const response = await axios.get( + `${process.env.NEXT_PUBLIC_API_URL}/team`, + { + withCredentials: true, + }, + ); + setTeamData(response.data); + } catch (e) { + if (axios.isAxiosError(e)) { + const axiosError = e as AxiosError; + switch (axiosError.response?.status) { + case 401: + void router.push("/"); + break; + case 404: + if (axiosError.response?.data.message === "user does not exist") { + router.push("/"); + } + break; + case 417: + setTeam(true); + console.log("no team"); + break; + case 200: + setTeam(true); + break; + default: + console.log(e); + break; + } + } + } + }; + + const fetchIdea = async () => { + try { + const response: AxiosResponse = await axios.get( + `${process.env.NEXT_PUBLIC_API_URL}/idea`, + { + withCredentials: true, + }, + ); + SetIdea("idea found"); + console.log("FETCH IDEA: ", response); + } catch (e) { + if (axios.isAxiosError(e)) { + const axiosError = e as AxiosError; + switch (axiosError.response?.status) { + case 401: + router.push("/"); + break; + case 404: + if (axiosError.response?.data.message === "user does not exist") { + router.push("/"); + } + console.log("no team"); + break; + case 417: + console.log("team no idea"); + break; + case 409: + setIdea(409); + break; + default: + console.log(e); + break; + } + } + } + }; + + useEffect(() => { + const fetchDataAndLogin = async () => { + // await login(); + await fetchData(); + await fetchIdea(); + }; + void fetchDataAndLogin(); + }, []); + + useEffect(() => { + if (user.data.team_id === "00000000-0000-0000-0000-000000000000") { + console.log("Loner saala"); + setTeam(true); + } else { + void fetchTeam(); + } + if (user.data.is_leader) { + console.log("Leader saala"); + setIsLeader(true); + } + if (user.data.is_leader) + if (user.data.id === teamData.team?.leader_id) { + setIsLeader(true); + } + }, []); + + const noTeamCard = [ + { + text: "+ Create Team", + showModal: true, + modalType: "CreateTeam", + }, + { + text: "Join Team", + showModal: true, + modalType: "JoinTeam", + }, + ]; + const ideaTherecard = [ + { + text: "View Idea", + showModal: true, + modalType: "IdeaSubmit", + }, + { + text: "Edit idea", + showModal: false, + modalType: "EditIdea", + routeTo: "/edit-idea", + }, + ]; + const ideaCard = [ + { + text: "Submit An Idea", + showModal: false, + modalType: idea === 409 ? "Choice" : "JoinTeam", + routeTo: "/submit-idea", + }, + ]; + + const notLeader = [ + { + text: "View Idea", + showModal: true, + modalType: "IdeaSubmit", + }, + ]; + + return ( + <> + +
+
+
+ + title +
+ + + {/* This bkl is causing Hydration Error */} + {/* */} + +
+ +
+
+ + + + Profile + + + + + Logout + + +
+
+
+
+ +
+
+ {team ? ( + + ) : ( + + )} + + +
+
+
+ + ); +} diff --git a/devsoc24-portal-fe/src/app/login/login-form.tsx b/devsoc24-portal-fe/src/app/login-form.tsx similarity index 99% rename from devsoc24-portal-fe/src/app/login/login-form.tsx rename to devsoc24-portal-fe/src/app/login-form.tsx index bd82d92..faaf096 100644 --- a/devsoc24-portal-fe/src/app/login/login-form.tsx +++ b/devsoc24-portal-fe/src/app/login-form.tsx @@ -56,7 +56,7 @@ export default function LoginForm() { void toast.promise(submitForm(), { loading: "Cooking...", success: (temp) => { - void router.push("/"); + void router.push("/home"); return `Logged in successfully!`; }, error: (err: AxiosError) => { diff --git a/devsoc24-portal-fe/src/app/login/page.tsx b/devsoc24-portal-fe/src/app/login/page.tsx deleted file mode 100644 index 18f17a8..0000000 --- a/devsoc24-portal-fe/src/app/login/page.tsx +++ /dev/null @@ -1,50 +0,0 @@ -"use client"; - -import React, { useEffect, useState } from "react"; -import Logo from "@/components/logo"; -import { Card, CardContent, CardHeader } from "@/components/ui/card"; -import Image from "next/image"; -import title from "@/assets/images/title.svg"; -import title2 from "@/assets/images/glitchtitle1.svg"; -import title3 from "@/assets/images/glitchtitle2.svg"; -import title4 from "@/assets/images/glitchtitle3.svg"; -import LoginForm from "./login-form"; - -export default function Page() { - const [currentTitleIndex, setCurrentTitleIndex] = useState(0); - const titles = [title, title2, title3, title4]; - - useEffect(() => { - const intervals = [2000, 400, 600, 400]; - - const interval = setInterval(() => { - setCurrentTitleIndex((prevIndex) => (prevIndex + 1) % titles.length); - }, intervals[currentTitleIndex]); - - return () => { - clearInterval(interval); - }; - }, [currentTitleIndex, titles.length]); - - return ( -
-
- -
-
- - - title - -
-

Welcome back!

-

Login to your account

-
- - - -
-
-
- ); -} diff --git a/devsoc24-portal-fe/src/app/page.tsx b/devsoc24-portal-fe/src/app/page.tsx index 7b1f1fd..18f17a8 100644 --- a/devsoc24-portal-fe/src/app/page.tsx +++ b/devsoc24-portal-fe/src/app/page.tsx @@ -1,339 +1,50 @@ "use client"; -import Image from "next/image"; -import { useRouter } from "next/navigation"; -import { useEffect, useState } from "react"; -import Logo from "@/components/logo"; -import Dashtitle from "@/assets/images/titleDashboard.svg"; -import CustomCard from "@/components/customCard"; -import TeamCard from "@/components/teamCard"; -import axios, { type AxiosResponse } from "axios"; -import { - useIdeaStore, - useLeaderStore, - useTeamDataStore, - useTeamStore, - useUserStore, -} from "@/store/store"; -import Loading from "./loading"; -import TrackComponent from "@/components/track/TrackComponent"; -import toast, { Toaster } from "react-hot-toast"; -import { refresh, type userProps } from "@/interfaces"; -import { type APIResponse } from "@/schemas/api"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; -import { Button } from "@/components/ui/button"; -import { User } from "lucide-react"; -import ToastContainer from "@/components/ToastContainer"; -import Link from "next/link"; -import TimelineComponent from "@/components/timeline/timelineComponent"; - -interface ideaProps { - message: string; - status: boolean; - data?: { - title: string; - description: string; - track: string; - github_link: string; - figma_link: string; - others: string; - }; -} - -interface teamProps { - data: { - token_expired?: boolean; - }; - message: string; - status: string; -} - -export default function HomePage() { - const router = useRouter(); - const { idea, setIdea } = useIdeaStore(); - const { team, setTeam } = useTeamStore(); - const { user, setUser } = useUserStore(); - const [getIdea, SetIdea] = useState(""); - const { teamData, setTeamData } = useTeamDataStore(); - const { isLeader, setIsLeader } = useLeaderStore(); - const logout = async () => { - try { - const response = await axios.post( - `${process.env.NEXT_PUBLIC_API_URL}/logout`, - { - nallaData: "", - }, - { - withCredentials: true, - }, - ); - localStorage.clear(); - void router.push("/login"); - } catch (e) { - if (axios.isAxiosError(e)) { - switch (e.response?.status) { - case 401: - await refresh(); - console.log("401"); - break; - default: - console.log(e); - break; - } - } - } - }; - - const handleLogout = async () => { - void toast.promise(logout(), { - loading: "Logging out...", - success: "Logged out successfully!", - error: "Something went wrong!", - }); - void router.push("/login"); - }; - - const fetchData = async () => { - try { - const response: AxiosResponse = await axios.get( - `${process.env.NEXT_PUBLIC_API_URL}/user/me`, - { - withCredentials: true, - }, - ); - console.log(response.data.data.is_leader); - setIsLeader(response.data.data.is_leader); - console.log(isLeader); - } catch (e) { - if (axios.isAxiosError(e)) { - switch (e.response?.status) { - case 401: - void router.push("/login"); - break; - case 404: - console.log("Idea Not found, but in a team"); - break; - case 409: - console.log("Not in team"); - break; - default: - console.log(e); - break; - } - } - } - }; - const fetchTeam = async () => { - try { - const response = await axios.get( - `${process.env.NEXT_PUBLIC_API_URL}/team`, - { - withCredentials: true, - }, - ); - setTeamData(response.data); - } catch (e) { - if (axios.isAxiosError(e)) { - switch (e.response?.status) { - case 401: - void router.push("/login"); - break; - case 417: - setTeam(true); - console.log("no team"); - break; - case 200: - setTeam(true); - break; - default: - console.log(e); - break; - } - } - } - }; - - const fetchIdea = async () => { - try { - const response: AxiosResponse = await axios.get( - `${process.env.NEXT_PUBLIC_API_URL}/idea`, - { - withCredentials: true, - }, - ); - SetIdea("idea found"); - console.log("FETCH IDEA: ", response); - } catch (e) { - if (axios.isAxiosError(e)) { - switch (e.response?.status) { - case 401: - router.push("/login"); - break; - case 404: - console.log("no team"); - break; - case 417: - console.log("team no idea"); - break; - case 409: - setIdea(409); - default: - console.log(e); - break; - } - } - } - }; +import React, { useEffect, useState } from "react"; +import Logo from "@/components/logo"; +import { Card, CardContent, CardHeader } from "@/components/ui/card"; +import Image from "next/image"; +import title from "@/assets/images/title.svg"; +import title2 from "@/assets/images/glitchtitle1.svg"; +import title3 from "@/assets/images/glitchtitle2.svg"; +import title4 from "@/assets/images/glitchtitle3.svg"; +import LoginForm from "./login-form"; - useEffect(() => { - const fetchDataAndLogin = async () => { - // await login(); - await fetchData(); - await fetchIdea(); - }; - void fetchDataAndLogin(); - }, []); +export default function Page() { + const [currentTitleIndex, setCurrentTitleIndex] = useState(0); + const titles = [title, title2, title3, title4]; useEffect(() => { - if (user.data.team_id === "00000000-0000-0000-0000-000000000000") { - console.log("Loner saala"); - setTeam(true); - } else { - void fetchTeam(); - } - if (user.data.is_leader) { - console.log("Leader saala"); - setIsLeader(true); - } - if (user.data.is_leader) - if (user.data.id === teamData.team?.leader_id) { - setIsLeader(true); - } - }, []); + const intervals = [2000, 400, 600, 400]; - const noTeamCard = [ - { - text: "+ Create Team", - showModal: true, - modalType: "CreateTeam", - }, - { - text: "Join Team", - showModal: true, - modalType: "JoinTeam", - }, - ]; - const ideaTherecard = [ - { - text: "View Idea", - showModal: true, - modalType: "IdeaSubmit", - }, - { - text: "Edit idea", - showModal: false, - modalType: "EditIdea", - routeTo: "/edit-idea", - }, - ]; - const ideaCard = [ - { - text: "Submit An Idea", - showModal: false, - modalType: idea === 409 ? "Choice" : "JoinTeam", - routeTo: "/submit-idea", - }, - ]; + const interval = setInterval(() => { + setCurrentTitleIndex((prevIndex) => (prevIndex + 1) % titles.length); + }, intervals[currentTitleIndex]); - const notLeader = [ - { - text: "View Idea", - showModal: true, - modalType: "IdeaSubmit", - }, - ]; + return () => { + clearInterval(interval); + }; + }, [currentTitleIndex, titles.length]); return ( - <> - -
-
-
- - title -
- - - {/* This bkl is causing Hydration Error */} - {/* */} - -
- -
-
- - - - Profile - - - - - Logout - - -
-
-
-
- -
-
- {team ? ( - - ) : ( - - )} - - +
+
+ +
+
+ + + title + +
+

Welcome back!

+

Login to your account

-
-
- + + + + +
+
); } diff --git a/devsoc24-portal-fe/src/app/reset/reset-form.tsx b/devsoc24-portal-fe/src/app/reset/reset-form.tsx index 633c11b..3956269 100644 --- a/devsoc24-portal-fe/src/app/reset/reset-form.tsx +++ b/devsoc24-portal-fe/src/app/reset/reset-form.tsx @@ -60,7 +60,7 @@ export default function ResetForm() { loading: "Cooking...", success: (temp) => { setTimeout(() => { - void router.push("/login"); + void router.push("/"); }, 1500); return `Password reset successfully!`; }, diff --git a/devsoc24-portal-fe/src/app/signup/details/team-form.tsx b/devsoc24-portal-fe/src/app/signup/details/team-form.tsx index 3df8ad9..53e5933 100644 --- a/devsoc24-portal-fe/src/app/signup/details/team-form.tsx +++ b/devsoc24-portal-fe/src/app/signup/details/team-form.tsx @@ -35,7 +35,7 @@ export default function TeamDetailsForm() { {isNewTeam ? : } diff --git a/devsoc24-portal-fe/src/app/signup/signup-form.tsx b/devsoc24-portal-fe/src/app/signup/signup-form.tsx index f99ec78..822a4b5 100644 --- a/devsoc24-portal-fe/src/app/signup/signup-form.tsx +++ b/devsoc24-portal-fe/src/app/signup/signup-form.tsx @@ -66,7 +66,7 @@ export default function SignupForm() { return `Account not found!`; case 409: setTimeout(() => { - void router.push("/login"); + void router.push("/"); }, 1500); return `Account already exists!`; case 400: diff --git a/devsoc24-portal-fe/src/app/submit-idea/submit-idea-form.tsx b/devsoc24-portal-fe/src/app/submit-idea/submit-idea-form.tsx index 89458c2..c92436c 100644 --- a/devsoc24-portal-fe/src/app/submit-idea/submit-idea-form.tsx +++ b/devsoc24-portal-fe/src/app/submit-idea/submit-idea-form.tsx @@ -66,7 +66,7 @@ export default function SubmitIdeaForm() { void toast.promise(handleSubmit(), { loading: "Cooking...", success: (temp) => { - void router.push("/"); + void router.push("/home"); return `Idea submitted successfully!`; }, error: (err: AxiosError) => { diff --git a/devsoc24-portal-fe/src/components/forms/create-team-form.tsx b/devsoc24-portal-fe/src/components/forms/create-team-form.tsx index cb519e0..73a8f58 100644 --- a/devsoc24-portal-fe/src/components/forms/create-team-form.tsx +++ b/devsoc24-portal-fe/src/components/forms/create-team-form.tsx @@ -48,7 +48,7 @@ export default function CreateTeamForm() { void toast.promise(handleSubmit(), { loading: "Cooking...", success: (temp) => { - void router.push("/"); + void router.push("/home"); return `Team created successfully!`; }, error: (err: AxiosError) => { diff --git a/devsoc24-portal-fe/src/components/forms/join-team-form.tsx b/devsoc24-portal-fe/src/components/forms/join-team-form.tsx index 7b88c9a..b78559f 100644 --- a/devsoc24-portal-fe/src/components/forms/join-team-form.tsx +++ b/devsoc24-portal-fe/src/components/forms/join-team-form.tsx @@ -57,7 +57,7 @@ export default function JoinTeamForm() { void toast.promise(handleSubmit(), { loading: "Cooking...", success: (temp) => { - void router.push("/"); + void router.push("/home"); return `Team joined successfully!`; }, error: (err: AxiosError) => { diff --git a/devsoc24-portal-fe/src/components/team/createTeam.tsx b/devsoc24-portal-fe/src/components/team/createTeam.tsx index 934848f..fd1d293 100644 --- a/devsoc24-portal-fe/src/components/team/createTeam.tsx +++ b/devsoc24-portal-fe/src/components/team/createTeam.tsx @@ -80,7 +80,7 @@ function CreateTeam() { if (axios.isAxiosError(e)) { switch (e.response?.status) { case 401: - void router.push("/login"); + void router.push("/"); break; case 417: setTeam(true); diff --git a/devsoc24-portal-fe/src/components/team/joinTeam.tsx b/devsoc24-portal-fe/src/components/team/joinTeam.tsx index c7706ac..a7c10ba 100644 --- a/devsoc24-portal-fe/src/components/team/joinTeam.tsx +++ b/devsoc24-portal-fe/src/components/team/joinTeam.tsx @@ -60,7 +60,7 @@ function JoinTeam() { if (axios.isAxiosError(e)) { switch (e.response?.status) { case 401: - void router.push("/login"); + void router.push("/"); break; case 417: setTeam(true); diff --git a/devsoc24-portal-fe/src/components/teamCard.tsx b/devsoc24-portal-fe/src/components/teamCard.tsx index 835aab2..dfa715f 100644 --- a/devsoc24-portal-fe/src/components/teamCard.tsx +++ b/devsoc24-portal-fe/src/components/teamCard.tsx @@ -3,12 +3,21 @@ import { Crown, BadgeMinus, Files, Check } from "lucide-react"; import { Button } from "@/components/ui/button"; import { CopyToClipboard } from "react-copy-to-clipboard"; import { teamDataProps, userProps } from "@/interfaces"; +import { Dialog, DialogTrigger } from "@/components/ui/dialog"; + import axios from "axios"; -import { useIdeaStore, useLeaderStore, useTeamEditStore, useTeamStore, useUserStore } from "@/store/store"; +import { + useIdeaStore, + useLeaderStore, + useTeamEditStore, + useTeamStore, + useUserStore, +} from "@/store/store"; import { useRouter } from "next/navigation"; import editImg from "@/assets/images/edit.svg"; import Image from "next/image"; import toast from "react-hot-toast"; +import LeaveTeam from "./team/leaveTeam"; interface keyProps { message: string; @@ -24,7 +33,11 @@ const TeamCard: React.FC = (props) => { const { idea, setIdea } = useIdeaStore(); const { edit, setEdit } = useTeamEditStore(); const { isLeader, setIsLeader } = useLeaderStore(); - const [showModal, setShowModal] = useState(false); + const [showModal, setShowModal] = useState(""); + + const handleDialogTriggerClick = (modalType: string) => { + setShowModal(modalType); + }; const router = useRouter(); @@ -41,14 +54,14 @@ const TeamCard: React.FC = (props) => { `${process.env.NEXT_PUBLIC_API_URL}/user/me`, { withCredentials: true, - } + }, ); setUser(response.data); } catch (e) { if (axios.isAxiosError(e)) { switch (e.response?.status) { case 401: - void router.push("/login"); + void router.push("/"); break; case 404: console.log("Idea Not found, but in a team"); @@ -84,7 +97,7 @@ const TeamCard: React.FC = (props) => { useEffect(() => { const leader = props.team?.users.find( - (item) => item.id === props.team?.leader_id + (item) => item.id === props.team?.leader_id, ); if (leader) { console.log("NAME:", leader.name); @@ -96,100 +109,100 @@ const TeamCard: React.FC = (props) => { setEdit(!edit); }; - const toggleModal = () => { - setShowModal(!showModal); - }; - return ( <>
-
-

Your Devsoc Team

- {isLeader ? ( -
- edit - Edit -
- ) : ( -
- edit - Leave Team -
- )} -
-
-

{props.team?.team_name}

-

Team Members

-
- {Leader} - - - -
- {props.team?.users - .filter((member) => member.name !== Leader) - .map((member, index) => ( + +
+

Your Devsoc Team

+ {isLeader ? (
- {member.name} - - {} - {edit ? : <>} - + edit + Edit
- ))} -
- {props.team && ( - - - - )} - {edit ? ( - ) : ( - <> + handleDialogTriggerClick("leave")} + > +
+ edit + Leave Team +
+
)}
-
+
+

{props.team?.team_name}

+

Team Members

+
+ {Leader} + + + +
+ {props.team?.users + .filter((member) => member.name !== Leader) + .map((member, index) => ( +
+ {member.name} + + handleDialogTriggerClick("leave")} + > + + {edit ? : <>} + + +
+ ))} +
+ {props.team && ( + + + + )} + {edit ? ( + handleDialogTriggerClick("leave")} + > + + + ) : ( + <> + )} +
+
+ {showModal === "leave" && } +