Skip to content

Commit

Permalink
✨ Major UI overhaul and API integration for real data (Taegon21#35)
Browse files Browse the repository at this point in the history
* 💄 Adjust sidebar UI size

* 💄 Set global font-family for font optimization

* 🔧 Configure proxy to bypass CORS

* 💄 Update UI to display user data managed by global state

* ✨ Reflect actual data using API

* 💄 Change API endpoint
  • Loading branch information
Taegon21 authored Jun 28, 2024
1 parent 185adb3 commit fda1f61
Show file tree
Hide file tree
Showing 17 changed files with 359 additions and 211 deletions.
53 changes: 36 additions & 17 deletions src/api/hooks/useProfessor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import apiClient from "@/api/client";
import { API_ENDPOINTS } from "@/api/endpoints";
import { useQuery, useMutation } from "@tanstack/react-query";
import { useUserStore } from "@/store/userStore";
import { type ICreateClassArgs, IDeleteClassArgs } from "@/type/interfaces";

const fetchCheck = async (professorId: string) => {
const { data } = await apiClient.get(
Expand All @@ -9,27 +11,16 @@ const fetchCheck = async (professorId: string) => {
return data;
};

export const useFetchCheck = (professorId: string) => {
export const useFetchCheck = () => {
const { studentId } = useUserStore();
return useQuery({
queryKey: ["fetchDeploy", professorId],
queryFn: () => fetchCheck(professorId),
queryKey: ["fetchDeploy", studentId],
queryFn: () => fetchCheck(studentId),
enabled: !!studentId,
});
};

interface ClassCreationData {
className: string;
studentIds: string[];
options: { [key: string]: string };
command: string[];
customScript: string;
}

interface CreateClassArgs {
professorId: string;
classData: ClassCreationData;
}

const createClass = async ({ professorId, classData }: CreateClassArgs) => {
const createClass = async ({ professorId, classData }: ICreateClassArgs) => {
const { data } = await apiClient.post(
API_ENDPOINTS.PROFESSOR.CREATE(professorId),
classData
Expand All @@ -40,5 +31,33 @@ const createClass = async ({ professorId, classData }: CreateClassArgs) => {
export const useCreateClass = () => {
return useMutation({
mutationFn: createClass,
onSuccess: (response) => {
alert("Container가 성공적으로 생성되었습니다.");
console.log("response", response);
},
onError: (error) => {
alert(`Error: ${error.message}`);
},
});
};

const deleteClass = async ({ professorId, deleteData }: IDeleteClassArgs) => {
const { data } = await apiClient.post(
API_ENDPOINTS.PROFESSOR.DELETE(professorId),
deleteData
);
return data;
};

export const useDeleteClass = () => {
return useMutation({
mutationFn: deleteClass,
onSuccess: (response) => {
alert("Container가 성공적으로 삭제되었습니다.");
console.log("response", response);
},
onError: (error) => {
alert(`Error: ${error.message}`);
},
});
};
13 changes: 10 additions & 3 deletions src/api/hooks/useStudent.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import apiClient from "@/api/client";
import { API_ENDPOINTS } from "@/api/endpoints";
import { useQuery } from "@tanstack/react-query";
import { useUserStore } from "@/store/userStore";

const fetchService = async (studentId: string) => {
const { data } = await apiClient.get(
Expand All @@ -19,23 +20,29 @@ const fetchDeploy = async (studentId: string) => {
return data;
};

export const useFetchService = (studentId: string) => {
export const useFetchService = () => {
const { studentId } = useUserStore();
return useQuery({
queryKey: ["fetchService", studentId],
queryFn: () => fetchService(studentId),
enabled: !!studentId,
});
};

export const useFetchPod = (studentId: string) => {
export const useFetchPod = () => {
const { studentId } = useUserStore();
return useQuery({
queryKey: ["fetchPod", studentId],
queryFn: () => fetchPod(studentId),
enabled: !!studentId,
});
};

export const useFetchDeploy = (studentId: string) => {
export const useFetchDeploy = () => {
const { studentId } = useUserStore();
return useQuery({
queryKey: ["fetchDeploy", studentId],
queryFn: () => fetchDeploy(studentId),
enabled: !!studentId,
});
};
41 changes: 9 additions & 32 deletions src/app/(main)/container/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
"use client";

import { useParams } from "next/navigation";
import { useState, useEffect } from "react";
import { useState } from "react";
import SearchIcon from "/public/icons/Search.svg";
import styles from "./page.module.css";
import Filter from "@/components/container/Filter";
import Container from "@/components/container/Container";
import dummyData from "@/data/dummy_container_data.json";
import { useFetchService } from "@/api/hooks/useStudent";
import { type ServiceSchema } from "@/type/schemas";

export default function Home() {
const { id: container } = useParams();
const { data: serviceData, isLoading, error } = useFetchService();

const [searchQuery, setSearchQuery] = useState("");
const [filteredContainers, setFilteredContainers] = useState(dummyData);
const [filterOption, setFilterOption] = useState("");

const [modalOpen, setModalOpen] = useState(false);

const titles = {
recent: "최근 실행 컨테이너",
semester: "이번 학기 컨테이너",
Expand All @@ -26,28 +25,6 @@ export default function Home() {
const title =
titles[container as keyof typeof titles] || "전체 학기 컨테이너";

useEffect(() => {
let filtered = dummyData;

if (searchQuery !== "") {
filtered = filtered.filter(
(c) =>
c.course_name.toLowerCase().includes(searchQuery.toLowerCase()) ||
c.professor_name.toLowerCase().includes(searchQuery.toLowerCase())
);
}

if (container === "recent" || filterOption === "recent") {
filtered = filtered.filter((c) =>
["Fall 2023", "Spring 2024"].includes(c.semester)
);
} else if (container === "semester" || filterOption === "semester") {
filtered = filtered.filter((c) => c.semester === "Spring 2024");
}

setFilteredContainers(filtered);
}, [searchQuery, filterOption, container]);

const handleSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
setSearchQuery(event.target.value);
};
Expand All @@ -56,9 +33,9 @@ export default function Home() {
setFilterOption(option);
};

const handleModalOpen = () => {
setModalOpen(true);
};
// 로딩과 에러 처리
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;

return (
<div className={styles.container}>
Expand All @@ -81,8 +58,8 @@ export default function Home() {
</div>
</div>
<div className={styles.results}>
{filteredContainers.map((container, index) => (
<Container key={index} {...container} />
{serviceData.map((container: ServiceSchema, index: number) => (
<Container key={index} serviceData={container} />
))}
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions src/app/(onboarding)/login/page.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@
align-items: center;
text-decoration: none;
cursor: pointer;
border: none;
outline: none;
}
.divierContent {
display: flex;
Expand Down
2 changes: 1 addition & 1 deletion src/app/(onboarding)/verify-email/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default function VerifyEmail() {
}
try {
await verifyEmail({ username: email, code });
router.push("/verify-email");
router.push("/login");
alert("Email verification successful! You can now login.");
} catch (err) {
console.error("Email verification failed:", err);
Expand Down
57 changes: 33 additions & 24 deletions src/app/(professor)/check-container/page.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,48 @@
"use client";
import { useState } from "react";
import styles from "./page.module.css";
import data from "@/data/dummy_check_data.json";
import PodTable from "@/components/check/PodTable";
import GridComponent from "@/components/check/PodGrid";

interface PodData {
name: string;
ip: string;
labels: {
app: string;
class_id: string;
pod_template_hash: string;
professor_id: string;
student_id: string;
vscode: string;
ssh: string;
};
creationTimestamp: string;
status: string;
}
import { useFetchCheck } from "@/api/hooks/useProfessor";
import { type ContainerCheckSchema } from "@/type/schemas";

const CheckPage = () => {
const [filterClassId, setFilterClassId] = useState<string>("");
const {
data: containerCheckData,
isLoading,
isError,
error,
} = useFetchCheck();

// 로딩 및 에러 처리

if (!containerCheckData) return;

if (isLoading) {
console.log("Loading...");
return <div>Loading...</div>;
}

if (isError) {
console.log("Error: ", error.message);
return <div>Error: {error.message}</div>;
}

const handleFilterChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
setFilterClassId(e.target.value);
};

const filteredData = data.filter((pod: PodData) => {
return filterClassId === "" || pod.labels.class_id === filterClassId;
});
const filteredData = containerCheckData.filter(
(pod: ContainerCheckSchema) => {
return filterClassId === "" || pod.labels.class_id === filterClassId;
}
);

const classIds = Array.from(
new Set(data.map((pod: PodData) => pod.labels.class_id))
const classIds: string[] = Array.from(
new Set(
containerCheckData.map((pod: ContainerCheckSchema) => pod.labels.class_id)
)
);

return (
Expand All @@ -48,8 +57,8 @@ const CheckPage = () => {
onChange={handleFilterChange}
>
<option value="">전체</option>
{classIds.map((classId) => (
<option key={classId} value={classId}>
{classIds.map((classId: string, index: number) => (
<option key={index} value={classId}>
{classId}
</option>
))}
Expand Down
21 changes: 21 additions & 0 deletions src/app/(professor)/create-container/page.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
font-weight: 500;
border: 1px solid #ccc;
border-radius: 12px;
width: 100%;

}

.submitButton {
Expand All @@ -78,6 +80,25 @@
cursor: pointer;
}

.studentIdRow {
display: flex;
justify-content: space-between;
gap: 10px;
margin-bottom: 10px;
}

.addButton,
.removeButton {
padding: 4px 12px;
font-size: 20px;
font-weight: 700;
color: white;
background-color: var(--orange-color);
border: none;
border-radius: 12px;
cursor: pointer;
}

@media (max-width: 768px) {
.leftContainer {
display: none;
Expand Down
Loading

0 comments on commit fda1f61

Please sign in to comment.