Skip to content

Commit

Permalink
[BBB-99] Feat: 책 스터디 대시보드 및 공지사항, 게시글 UI
Browse files Browse the repository at this point in the history
  • Loading branch information
msjang4 committed Aug 13, 2024
1 parent 6ebbd0e commit 5ecd73b
Show file tree
Hide file tree
Showing 13 changed files with 652 additions and 49 deletions.
142 changes: 142 additions & 0 deletions app/post/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/**
* This code was generated by v0 by Vercel.
* @see https://v0.dev/t/EYJ4s50uN2T
* Documentation: https://v0.dev/docs#integrating-generated-code-into-your-nextjs-app
*/

/** Add fonts into your Next.js project:
import { Libre_Baskerville } from 'next/font/google'
libre_baskerville({
subsets: ['latin'],
display: 'swap',
})
To read more about using these font, please visit the Next.js documentation:
- App Directory: https://nextjs.org/docs/app/building-your-application/optimizing/fonts
- Pages Directory: https://nextjs.org/docs/pages/building-your-application/optimizing/fonts
**/
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';

export default function post() {
return (
<div className="container mx-auto px-4 py-12 md:px-6 lg:py-16">
<article className="prose prose-gray mx-auto dark:prose-invert">
<div className="space-y-2 not-prose">
<h1 className="text-4xl font-extrabold tracking-tight lg:text-5xl">
스터디 입장전 필독
</h1>
<div className="flex items-center space-x-4 text-sm text-muted-foreground">
<div className="flex items-center space-x-2">
<Avatar className="h-6 w-6 border">
<AvatarImage src="/placeholder-user.jpg" alt="@shadcn" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
<span>John Doe</span>
</div>
<span>|</span>
<span>August 13, 2024</span>
</div>
</div>

<p>
스터디 구성 최소 조건 요약 스터디 주기 및 인원 최소 4-6주 이상 지속
매주 또는 격주 진행 2시간 이내<br></br>
<br></br> 중간 쉬는시간 갖기 인원 4-8명 참여자 스터디 리더 스터디 방향
길잡이 매회차 스터디 사전 질문 준비 스터디원 공부 반드시 하고 참여하기
<br></br> 본인이 이해한 부분 설명, 못한 부분 질문 기록 남기기 모든
참여자 - 발표내용에 대한 질문, 코멘트, 새로 배운 것, 중요한 부분 등
최소 3개 이상 공유 지원자 - 공유 내용 취합 및 정리 후 공개 장소에 기록
<br></br> 규칙 공부 내용과 관련된 모든 질문 환영
비난/비방/욕/뒷담화/무시 등 절대 금지 정신 <br></br>
<br></br>1. 지식의 소화전 자신의 직업 또는 관심 분야에서 뛰어난 도서,
아티클, 강연을 찾아서 그것들을 깊이있게 공부하기 공부재료 찾는 방법 -
분야를 잘 아는 사람에게 좋아하는 책/작가, 영향을 받은 것들에 대해
물어보기 재료를 찾았으면 스터디 그룹 참여하기 공부 순서 정하기 공부
목록 구성하기<br></br> 2. 통찰력 웅덩이 혼자 공부한 내용을 스터디에서
나누기 공부하면서 헷갈렸던 부분 잘못 이해한 부분 새로 알게된 사실
몰랐던 부분이 어디인지 확실히 알게 됨 내가 모르는 것은 질문하고 아는
것은 설명하기 가장 좋은 스터디 그룹은 다른 사람과 같이 배우는 것을
편안하게 느낄 수 있는 곳 분위기는 대화하는데 중요한 역할을 함 질 높은
스터디를 위한 스터디 리더와 스터디원이 필요 <br></br>3. 안전한 공간 안
좋은 예시 자랑, 따돌림, 무시하는 말투, 무례하거나 싸우자 식의 태도
지나치게 한명만 많이 말하는 상황 개인에 대한 비난/비방 개인적 의견
충돌이 있을 때는 스터디가 끝난 후 따로 대화시간 갖기 스터디 내에서
따르는 규칙 정하기 어떤 질문이나 실수도 용인되는 환경 만들기<br></br>{' '}
4. 지속력 빈도 - 매주 또는 격주 시간 - 2시간 이내, 일찍 끝나면 그대로
스터디 종료 중간에 쉬는시간 갖기 참여자들이 실제로 관심 있어하는
주제에 대해서 다루기 이상적인 스터디 공간과 환경 갖추기 서브그룹과
스터디 주기 적절히 활용하기<br></br> 5. 동료 찾기 사내 스터디 -
성공확률 반반 컨퍼런스, 강연 등 큰 집단은 커넥션이 약하고 비효율적
작은 스터디를 지속하면서 본인이 실제로 관심있는 주제를 같이 공부하는
것이 가장 효율적 의미있는 네트워킹(관계형성)은 안전한 공간에서 제일 잘
이루어짐 네트워킹에 가장 좋은 시간대는 스터디 전/후
</p>
</article>
<div className="mx-auto mt-12 max-w-3xl space-y-6">
<h2 className="text-2xl font-bold">Comments</h2>
<div className="space-y-6">
<div className="flex items-start gap-4">
<Avatar className="h-10 w-10 border">
<AvatarImage src="/placeholder-user.jpg" alt="@shadcn" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
<div className="flex-1 space-y-2">
<div className="flex items-center justify-between">
<div className="font-medium">Jane Doe</div>
<div className="text-sm text-muted-foreground">
August 13, 2024
</div>
</div>
<p>
This is a great article! I really enjoyed learning about the
future of web development and the importance of automation and
collaboration. Can't wait to see what the future holds.
</p>
</div>
</div>
<div className="flex items-start gap-4">
<Avatar className="h-10 w-10 border">
<AvatarImage src="/placeholder-user.jpg" alt="@shadcn" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
<div className="flex-1 space-y-2">
<div className="flex items-center justify-between">
<div className="font-medium">John Smith</div>
<div className="text-sm text-muted-foreground">
August 14, 2024
</div>
</div>
<p>
Excellent insights! I'm really excited about the potential of AI
and machine learning in web development. Can't wait to see how
these technologies will shape the future.
</p>
</div>
</div>
<div className="flex items-start gap-4">
<Avatar className="h-10 w-10 border">
<AvatarImage src="/placeholder-user.jpg" alt="@shadcn" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
<div className="flex-1 space-y-2">
<div className="flex items-center justify-between">
<div className="font-medium">Emily Johnson</div>
<div className="text-sm text-muted-foreground">
August 15, 2024
</div>
</div>
<p>
This article really resonates with me. I've been seeing the
benefits of automation and collaboration in my own work, and I'm
excited to see how the industry continues to evolve. Thanks for
the great insights!
</p>
</div>
</div>
</div>
</div>
</div>
);
}
76 changes: 76 additions & 0 deletions app/study/[id]/board/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
'use client';

import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle
} from '@/components/ui/card/card';
import { CalendarIcon } from '@/components/ui/icon/icon';

export default function Signup() {
return (
<div className="flex justify-center">
<div className="mt-5 flex flex-col w-1/3 gap-5 justify-start">
<Card className="relative overflow-hidden rounded-lg shadow-lg transition-transform duration-300 ease-in-out hover:-translate-y-2 hover:shadow-xl">
<CardHeader className="bg-primary p-4 text-primary-foreground">
<CardTitle className="text-xl font-bold">
스터디 입장 전 필독
</CardTitle>
<CardDescription className="text-base">
오프라인 주 1회
</CardDescription>
</CardHeader>
<CardContent className="flex p-4 gap-2">
<CalendarIcon className="w-4 h-4"></CalendarIcon>
<p className="text-sm text-muted-foreground">8월 17일 </p>
</CardContent>
</Card>
<Card className="relative overflow-hidden rounded-lg shadow-lg transition-transform duration-300 ease-in-out hover:-translate-y-2 hover:shadow-xl">
<CardHeader className="bg-primary p-4 text-primary-foreground">
<CardTitle className="text-xl font-bold">
스터디 입장 전 필독
</CardTitle>
<CardDescription className="text-base">
오프라인 주 1회
</CardDescription>
</CardHeader>
<CardContent className="flex p-4 gap-2">
<CalendarIcon className="w-4 h-4"></CalendarIcon>
<p className="text-sm text-muted-foreground">8월 17일 </p>
</CardContent>
</Card>
<Card className="relative overflow-hidden rounded-lg shadow-lg transition-transform duration-300 ease-in-out hover:-translate-y-2 hover:shadow-xl">
<CardHeader className="bg-primary p-4 text-primary-foreground">
<CardTitle className="text-xl font-bold">
스터디 입장 전 필독
</CardTitle>
<CardDescription className="text-base">
오프라인 주 1회
</CardDescription>
</CardHeader>
<CardContent className="flex p-4 gap-2">
<CalendarIcon className="w-4 h-4"></CalendarIcon>
<p className="text-sm text-muted-foreground">8월 17일 </p>
</CardContent>
</Card>

<Card className="relative overflow-hidden rounded-lg shadow-lg transition-transform duration-300 ease-in-out hover:-translate-y-2 hover:shadow-xl">
<CardHeader className="bg-primary p-4 text-primary-foreground">
<CardTitle className="text-xl font-bold">
스터디 입장 전 필독
</CardTitle>
<CardDescription className="text-base">
오프라인 주 1회
</CardDescription>
</CardHeader>
<CardContent className="flex p-4 gap-2">
<CalendarIcon className="w-4 h-4"></CalendarIcon>
<p className="text-sm text-muted-foreground">8월 17일 </p>
</CardContent>
</Card>
</div>
</div>
);
}
8 changes: 2 additions & 6 deletions app/study/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ import Spinner from '@/components/ui/spinner/spinner';
import getStudyDetails from '@/lib/api/study/get-details';
import startStudy from '@/lib/api/study/start';
import { userState } from '@/recoil/userAtom';
import {
AlgorithmRound,
StudyDetails,
StudyStatus
} from '@/types/study/study-detail';
import { Round, StudyDetails, StudyStatus } from '@/types/study/study-detail';
import { toast } from 'react-toastify';
import { useRecoilState } from 'recoil';

Expand All @@ -25,7 +21,7 @@ export default function StudyPage() {
const studyId = Number(params.id);

const [details, setDetails] = useState<StudyDetails | undefined>();
const [round, setRound] = useState<AlgorithmRound | undefined>();
const [round, setRound] = useState<Round | undefined>();
const [isParticipant, setIsParticipant] = useState(false);
const [canStart, setCanStart] = useState(false);
const [myData, setMyData] = useRecoilState(userState);
Expand Down
37 changes: 37 additions & 0 deletions components/study/dashboard/about.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {
AvatarFallback,
AvatarImage
} from '@/components/ui/avatar/avatar';
import { BellIcon, BoxIcon, FilePenIcon } from '@/components/ui/icon/icon';
import { StudyType } from '@/constants/study/study';
import { StudyDetails, StudyMemberInfo } from '@/types/study/study-detail';

export default function StudyAbout({
Expand All @@ -21,8 +23,17 @@ export default function StudyAbout({
<h2 className="text-xl font-bold">소개</h2>
<SettingsIcon className="w-5 h-5 text-muted-foreground" />
</div>

<p className="mt-2 text-muted-foreground">{details.introduce}</p>

<div className="mt-4 space-y-2">
<div
onClick={() => {}}
className="group w-fit hover:text-gray-900 text-blue-600 flex items-center space-x-2"
>
<BellIcon className="group-hover:stroke-black stroke-blue w-5 h-5 text-muted-foreground"></BellIcon>
<b>공지사항 </b>
</div>
<div className="flex items-center space-x-2">
<ActivityIcon className="w-5 h-5 text-muted-foreground" />
<b>
Expand Down Expand Up @@ -57,6 +68,32 @@ export default function StudyAbout({
<b>{details.reliabilityLimit}</b>
<span>이상</span>
</div>
{StudyType[details.studyType as keyof typeof StudyType] ===
StudyType.BOOK && (
<>
<div className="flex items-center space-x-2">
<BookIcon className="w-5 h-5 text-muted-foreground" />
{/* TODO details.book.title로 변경 */}
<span>자바의 정석</span>
</div>

<div
onClick={() => {}}
className="group w-fit hover:text-gray-900 text-blue-600 flex items-center space-x-2"
>
<FilePenIcon className="group-hover:stroke-black stroke-blue w-5 h-5 text-muted-foreground"></FilePenIcon>
<b>과제 선택지 수정 </b>
</div>

<div
onClick={() => {}}
className="group w-fit hover:text-gray-900 text-blue-600 flex items-center space-x-2"
>
<BoxIcon className="group-hover:stroke-black stroke-blue w-5 h-5 text-muted-foreground"></BoxIcon>
<b>과제 투표 </b>
</div>
</>
)}
</div>
<div className="mt-6">
<h3 className="text-lg font-bold">
Expand Down
81 changes: 81 additions & 0 deletions components/study/dashboard/book-row.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { PlayIcon, PuzzleIcon, XIcon } from '@/components/ui/icon/icon';
import { TableCell, TableRow } from '@/components/ui/table/table';
import {
AlgorithmProblemInfo,
BookMemberInfo,
StudyAssignmentInfo
} from '@/types/study/study-detail';

import { Button } from '@/components/ui/button/button';
import { userState } from '@/recoil/userAtom';
import { useState } from 'react';
import { useRecoilState } from 'recoil';

export function BookRow({
studyId,
roundIdx,
userId,
assignment,
user
}: {
studyId: number;
roundIdx: number;
userId: number;
assignment: StudyAssignmentInfo;
user: BookMemberInfo;
}) {
const [isLoading, setIsLoading] = useState(false);
const [my, _] = useRecoilState(userState);
return (
<TableRow>
<TableCell className="text-center">
<p className="text-center">{user.username}</p>
</TableCell>

<TableCell className="text-center">
<p className="text-center">{assignment.content}</p>
</TableCell>
<TableCell className="text-center">
<div className="flex items-center justify-center">
{user.video ? (
<Button className="px-3 py-1 hover:bg-gray-600 bg-gray-900 flex items-center justify-center">
<PlayIcon className="w-5 h-5 stroke-white" />
</Button>
) : (
<XIcon className="w-5 h-5 text-muted-foreground" />
)}
</div>
</TableCell>

<TableCell className="text-center">
<div className="flex items-center justify-center">
{user.quiz ? (
<Button className="px-3 py-1 hover:bg-gray-600 bg-gray-900 flex items-center justify-center">
<PuzzleIcon className="w-5 h-5 stroke-white" />
</Button>
) : (
<XIcon className="w-5 h-5 text-muted-foreground" />
)}
</div>
</TableCell>
</TableRow>
);
}

const createRefIdToProblemIdMap = (problems: {
[problemId: number]: AlgorithmProblemInfo;
}) => {
const map: { [refId: number]: number } = {};
Object.entries(problems).forEach(([key, problem]) => {
map[problem.refId] = Number(key);
});
return map;
};

const getSolvedProblemRefIds = (res: any) => {
const solvedProblemRefIds: number[] = [];
res.data.items.forEach((item: any) => {
solvedProblemRefIds.push(item.problemId);
});
return solvedProblemRefIds;
};
Loading

0 comments on commit 5ecd73b

Please sign in to comment.