Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions frontend/src/api/session-list/getSessionList.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import { api } from "@/api/config/axios.ts";
import { Session } from "@/pages/SessionListPage/types/session";

export const getSessionList = async (): Promise<Session[]> => {
const response = await api.get("api/rooms");
interface GetSessionListRequest {
inProgress: 0 | 1;
}

export const getSessionList = async ({
inProgress = 0,
}: GetSessionListRequest): Promise<Session[]> => {
const response = await api.get("api/rooms", {
params: {
inProgress
}
});

return response.data;
};
4 changes: 3 additions & 1 deletion frontend/src/components/common/Input/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ interface Props {

const SearchBar = ({ text }: Props) => {
return (
<div className="relative w-full h-11 flex items-center text-gray-400 dark:text-white fill-current">
<div
className={`relative w-full h-11 flex items-center text-gray-400 dark:text-white fill-current`}
>
<IoIosSearch className=" absolute left-4 w-5 h-5" />
<input
className={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ const Category = ({ tabName, tabText }: Props) => {
return (
<button
className={`flex flex-row gap-1
${tab === tabName
${
tab === tabName
? "text-bold-s text-green-500"
: "text-medium-l text-gray-400"
}`}
}`}
onClick={() => setTab(tabName)}
>
<span
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Category from "./Category";

const CategoryTap = () => {
const CategoryTab = () => {
return (
<section className="flex items-center gap-2">
<Category tabName="myList" tabText="나의 질문지" />
Expand All @@ -9,4 +9,4 @@ const CategoryTap = () => {
);
};

export default CategoryTap;
export default CategoryTab;
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,10 @@ const QuestionItem = ({ item }: { item: QuestionList }) => {
</div>
<button
className={`flex items-center ml-auto w-10 h-10 rounded-custom-m
${isSelected
? "bg-green-200 text-green-50"
: "bg-gray-300 text-gray-50"
${
isSelected
? "bg-green-200 text-green-50"
: "bg-gray-300 text-gray-50"
}`}
onClick={() => {
checkHandler(item.id, item.title);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState } from "react";
import { IoMdClose } from "react-icons/io";
import CategoryTap from "@components/sessions/create/SessionForm/ListSelectModal/CategoryTab";
import CategoryTab from "@components/sessions/create/SessionForm/ListSelectModal/CategoryTab";
import SearchBar from "@/components/common/Input/SearchBar";
import QuestionList from "./QuestionList";
import useSessionFormStore from "@/pages/CreateSessionPage/stores/useSessionFormStore";
Expand Down Expand Up @@ -59,7 +59,7 @@ const ListSelectModal = ({ modal: { dialogRef, closeModal } }: ModalProps) => {
>
<div className="flex p-8">
<h3 className="text-bold-m text-gray-black mr-6">질문 리스트</h3>
<CategoryTap />
<CategoryTab />
<button className="ml-auto" onClick={closeHandler}>
<IoMdClose className="text-gray-black w-7 h-7" />
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ const ParticipantButton = ({ selectedValue, onClick }: Props) => {
return (
<button
className={`flex-grow rounded-custom-m
${participant === selectedValue
${
participant === selectedValue
? "bg-green-50 border-2 border-green-200 text-semibold-r text-green-600"
: "bg-gray-white border border-gray-100 text-medium-m text-gray-400"
}`}
}`}
onClick={onClick}
>
{selectedValue}명
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import QuestionForm from "./view/QuestionForm.tsx";
import { IoArrowBackSharp } from "react-icons/io5";
import { Link } from "react-router-dom";
import SidebarPageLayout from "@components/layout/SidebarPageLayout.tsx";
import QuestionForm from "./view/QuestionForm";

const CreateQuestionPage = () => {
return (
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/CreateSessionPage/CreateSessionPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const CreateSessionPage = () => {
onClick={() => navigate("/sessions")}
>
<IoArrowBackSharp className="w-5 h-5" />
<span>면접 채널로 돌아가기</span>
<span>스터디 채널로 돌아가기</span>
</button>
<h1 className="text-bold-l mb-2">새로운 스터디 세션 만들기</h1>
<p className="text-medium-l text-gray-400 mb-8">
Expand Down
63 changes: 28 additions & 35 deletions frontend/src/pages/SessionListPage/SessionListPage.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,50 @@
import { useState } from "react";
import { IoMdAdd } from "react-icons/io";
import SearchBar from "@/components/common/Input/SearchBar";
import CategorySelect from "@/components/common/Select/CategorySelect";
import SessionList from "@/pages/SessionListPage/view/list/SessionList.tsx";
import CreateButton from "@/components/common/Button/CreateButton";
import SearchBar from "@components/common/Input/SearchBar";
import CategorySelect from "@components/common/Select/CategorySelect";
import { options } from "@/constants/CategoryData.ts";
import { useGetSessionList } from "@/pages/SessionListPage/api/useGetSessionList.ts";
import ErrorBlock from "@components/common/Error/ErrorBlock.tsx";
import SidebarPageLayout from "@components/layout/SidebarPageLayout.tsx";
import Divider from "@components/common/Divider.tsx";
import TabContainer from "./view/TabContainer";
import { Link } from "react-router-dom";
import { useGetSessionList } from "./api/useGetSessionList";
import SessionList from "./view/SessionList";
import ErrorBlock from "@components/common/Error/ErrorBlock";

const SessionListPage = () => {
const [selectedCategory, setSelectedCategory] = useState<string>("전체");

console.log(selectedCategory);

const { data: sessions, error, isLoading: listLoading } = useGetSessionList();

const [sessionList, inProgressList] = [
sessions ? sessions.filter((session) => !session.inProgress) : [],
sessions ? sessions.filter((session) => session.inProgress) : [],
];
const [currentTab, setCurrentTab] = useState<0 | 1>(0);
const [_, setSelectedCategory] = useState<string>("전체");
const {
data: sessionList,
isLoading,
error,
} = useGetSessionList({ inProgress: currentTab });

return (
<SidebarPageLayout>
<div className={"flex flex-col gap-8 max-w-6xl w-full px-12 pt-20 pb-4"}>
<div>
<div className="mb-4">
<h1 className={"text-bold-l mb-6"}>스터디 채널</h1>
<div className={"h-11 flex gap-2 w-full"}>
<SearchBar text="세션을 검색하세요" />
<CategorySelect
value={"FE"}
setValue={setSelectedCategory}
options={options}
/>
<CreateButton
path={"/sessions/create"}
text={"새로운 세션"}
icon={IoMdAdd}
/>
<SearchBar text="세션을 검색하세요" />
</div>
</div>
<SessionList
listTitle={"열려있는 공개 세션 목록"}
listLoading={listLoading}
sessionList={sessionList}
/>
<Divider isText={false} />
<SessionList
listTitle={"진행 중인 세션 목록"}
listLoading={listLoading}
sessionList={inProgressList}
/>
<div className="relative flex justify-between">
<TabContainer currentTab={currentTab} setCurrentTab={setCurrentTab} />
<Link
to="/sessions/create"
className="flex items-center gap-1 text-semibold-m text-gray-black pr-1 pb-2 hover:text-green-400"
>
<IoMdAdd />
<span>세션 생성하기</span>
</Link>
<div className="absolute bottom-0 -z-10 w-full h-0.1 bg-gray-100" />
</div>
<SessionList sessionList={sessionList || []} listLoading={isLoading} />
<ErrorBlock
error={error}
message={"서버에서 세션 목록을 불러오는데 실패했습니다!"}
Expand Down
10 changes: 7 additions & 3 deletions frontend/src/pages/SessionListPage/api/useGetSessionList.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { useQuery } from "@tanstack/react-query";
import { getSessionList } from "@/api/session-list/getSessionList.ts";

export const useGetSessionList = () => {
interface SessionListRequest {
inProgress: 0 | 1;
}

export const useGetSessionList = ({ inProgress }: SessionListRequest) => {
const { data, isLoading, error } = useQuery({
queryKey: ["sessionList"],
queryFn: () => getSessionList(),
queryKey: ["sessionList", inProgress],
queryFn: () => getSessionList({ inProgress }),
staleTime: 60 * 1000,
refetchInterval: 60 * 1000,
refetchOnMount: true,
Expand Down
70 changes: 27 additions & 43 deletions frontend/src/pages/SessionListPage/view/SessionCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { FaUserGroup } from "react-icons/fa6";
import { IoArrowForwardSharp } from "react-icons/io5";
import { Link } from "react-router-dom";
import type { Session } from "@/pages/SessionListPage/types/session";

Expand All @@ -20,52 +19,37 @@ const SessionCard = ({
onEnter,
}: SessionCardProps) => {
return (
<li
className={`relative flex rounded-custom-l border-l-[1.625rem] ${inProgress ? "border-l-point-2" : "border-l-green-200"} bg-gray-white shadow-8 overflow-hidden py-3 min-w-96 max-w-[47.5rem] h-[8.75rem] transition-all hover:shadow-lg group`}
<Link
onClick={onEnter}
to={`/session/${id}`}
className={`relative h-52 bg-white rounded-custom-m px-5 py-6 transition-all duration-200 ease-in-out hover:-translate-y-1.5 shadow-8
${inProgress === false ? "hover:shadow-16 hover:ring-1 hover:ring-green-200" : ""}`}
>
<div className={"flex-grow px-[0.75rem] flex flex-col items-start"}>
<span
className={
"text-medium-xs border-[0.0875rem] border-green-600 rounded-2xl py-px px-2"
}
>
{category[0]}
</span>
<Link className={""} onClick={onEnter} to={`/session/${id}`}>
<h3 className={"text-semibold-m mt-[0.5rem]"}>{title}</h3>
</Link>
<p className={"text-medium-r text-gray-400 dark:text-gray-300"}>
{questionListTitle ?? "함께 면접 스터디에 참여해보세요!"}
</p>
<div
className={
"absolute bottom-[0.75rem] left-0 px-[0.75rem] inline-flex items-center justify-between w-full"
}
>
<div className={"text-medium-s inline-flex items-center gap-1"}>
<span>{host} • </span>
<span className={"inline-flex items-center gap-1"}>
<FaUserGroup className="text-green-400" />{" "}
<span className={"inline-flex items-center"}>참여자</span>
{participants}/{maxParticipants}명
</span>
<div className="flex flex-col justify-between">
<div className={"flex-grow flex flex-col items-start"}>
<span
className={
"text-semibold-s text-green-600 bg-green-50 border-custom-s border-gray-300 rounded-2xl py-px px-2"
}
>
{category[0]}
</span>
<div className="px-0.5">
<h3 className={"text-semibold-m mt-2 mb-0.5"}>{title}</h3>
<p className={"text-medium-m text-gray-400"}>
{questionListTitle ?? "함께 면접 스터디에 참여해보세요!"}
</p>
<div className={"absolute bottom-5 left-6 text-medium-r flex flex-col"}>
<span className="text-gray-600">{host}</span>
<span className={"text-gray-black flex gap-2 items-center"}>
<FaUserGroup className="text-green-400" />
참여자 {participants}/{maxParticipants}명
</span>
</div>
</div>
{!inProgress && (
<Link to={`/session/${id}`}>
<button
className={
"text-semibold-r text-green-500 inline-flex items-center gap-[0.5rem] group-hover:gap-[0.375rem] transition-all"
}
onClick={onEnter}
>
<span>참여하기</span>{" "}
<IoArrowForwardSharp className="w-[1.25rem] h-[1.25rem] text-green-500" />
</button>
</Link>
)}
</div>
</div>
</li>
</Link>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,11 @@ import type { Session } from "@/pages/SessionListPage/types/session";
import NotFound from "@components/common/Animate/NotFound.tsx";

interface SessionListProps {
listTitle: string;
listLoading: boolean;
sessionList: Session[];
}

const SessionList = ({
listTitle,
listLoading,
sessionList,
}: SessionListProps) => {
const SessionList = ({ listLoading, sessionList }: SessionListProps) => {
const toast = useToast();
const renderSessionList = () => {
return sessionList.map((session) => {
Expand All @@ -40,9 +35,8 @@ const SessionList = ({

return (
<div>
<h2 className={"text-semibold-l mb-4"}>{listTitle}</h2>
{listLoading && <LoadingIndicator loadingState={listLoading} />}
<ul className={"grid grid-cols-1 xl:grid-cols-2 gap-4"}>
<ul className={"grid grid-cols-2 lg:grid-cols-3 gap-4"}>
{!listLoading && sessionList.length <= 0 ? (
<li key={-1} className={"flex justify-center items-center"}>
<NotFound
Expand Down
35 changes: 35 additions & 0 deletions frontend/src/pages/SessionListPage/view/Tab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
interface TabProps {
currentTab: 0 | 1;
tabStatus: 0 | 1;
setCurrentTab: React.Dispatch<React.SetStateAction<0 | 1>>;
}

const tabName = {
0: "공개된 세션",
1: "진행 중인 세션",
};

const Tab = ({ currentTab, tabStatus, setCurrentTab }: TabProps) => {
return (
<button
className={`flex flex-row gap-1
${currentTab === tabStatus
? "text-bold-s text-green-400"
: "text-medium-l text-gray-400"
}`}
onClick={() => setCurrentTab(tabStatus)}
>
<span
className={`px-1 pb-1.5 border-b-2
${currentTab === tabStatus ? "border-green-400" : "border-transparent"}`}
>
{tabName[tabStatus]}
</span>
<div
className={`border-b-2 ${currentTab === tabStatus ? "border-green-400" : "border-transparent"} transition-all duration-200`}
/>
</button>
);
};

export default Tab;
Loading