Skip to content

Commit

Permalink
✨ 홈화면 개선 (#184)
Browse files Browse the repository at this point in the history
  • Loading branch information
woohm402 authored Sep 25, 2024
1 parent e857303 commit 69a97f4
Show file tree
Hide file tree
Showing 17 changed files with 161 additions and 56 deletions.
10 changes: 3 additions & 7 deletions .github/workflows/frontend-lecture-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,9 @@ jobs:
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v3
with:
node-version: "20"
- name: Install dependencies
run: yarn install
- name: Run Lint
run: yarn lint
- name: Run Format
run: yarn format
- name: Check Types
run: yarn check-types
- name: Knip
run: yarn knip
run: yarn check-all
10 changes: 9 additions & 1 deletion frontend/lecture/eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import react from '@woohm402/eslint-config-react';

export default [
{ ignores: ['eslint.config.js', '.yarn', 'postcss.config.js', 'dist'] },
{
ignores: [
'.yarn',
'dist',
'eslint.config.js',
'node_modules',
'postcss.config.js',
],
},
...react({
tsconfigRootDir: import.meta.dirname,
}),
Expand Down
9 changes: 5 additions & 4 deletions frontend/lecture/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"check-types": "tsc",
"lint": "eslint .",
"format": "prettier . --check",
"check-all": "yarn check-types && yarn lint && yarn format && yarn knip"
"types:check": "tsc",
"lint:check": "eslint .",
"format:check": "prettier . --check",
"unused:check": "knip",
"check-all": "yarn types:check && yarn lint:check && yarn format:check && yarn unused:check"
},
"dependencies": {
"@radix-ui/react-dialog": "1.1.1",
Expand Down
83 changes: 52 additions & 31 deletions frontend/lecture/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import {
ChevronLeftIcon,
ChevronRightIcon,
} from '@radix-ui/react-icons';
import { Suspense, useCallback, useEffect, useState } from 'react';
import {
type PropsWithChildren,
Suspense,
useCallback,
useEffect,
useState,
} from 'react';
import { Link, Route, Routes, useLocation } from 'react-router-dom';

import { ThemeToggle } from '@/components/ThemeToggle';
Expand Down Expand Up @@ -51,12 +57,12 @@ const Sidebar = () => {
<div className="relative flex">
<div
className={cn(
'flex flex-col overflow-hidden py-4 bg-blend-darken',
'flex flex-col overflow-hidden py-8 bg-blend-darken',
isOpen ? 'w-52' : 'w-0',
)}
>
<Link to="/">
<h1 className="text-center text-3xl font-bold">Lecture</h1>
<h1 className="text-center text-3xl font-bold">Frontend</h1>
</Link>
<Tabs
className="mx-4 mt-8"
Expand All @@ -74,19 +80,11 @@ const Sidebar = () => {
<ul className="mt-4 flex flex-col gap-4">
{pages.flatMap((page) =>
tab === 'assignment' && page.type === 'assignment' ? (
<li
key={page.path}
className={
Date.now() > page.due.getTime() ? 'opacity-50' : undefined
}
>
<Link
to={page.path}
className={`flex flex-col gap-1 rounded-sm px-4 py-2 transition-colors hover:bg-slate-200 dark:hover:bg-slate-800 ${
currentPath === page.path
? 'bg-blue-100 font-semibold dark:bg-blue-900'
: ''
}`}
<li key={page.path}>
<PageLink
path={page.path}
isExpired={Date.now() > page.due.getTime()}
currentPath={currentPath}
>
<h3 className="text-base">{page.title}</h3>
<p className="flex items-center gap-2 text-xs text-slate-500">
Expand All @@ -96,30 +94,22 @@ const Sidebar = () => {
`${MM}${DD}${HH}:${mm}:${ss}까지`,
)}
</p>
</Link>
</PageLink>
</li>
) : tab === 'lecture' && page.type === 'lecture' ? (
<li
key={page.path}
className={
Date.now() > page.date.getTime() ? 'opacity-50' : undefined
}
>
<Link
to={page.path}
className={`flex flex-col gap-1 rounded-sm px-4 py-2 transition-colors hover:bg-slate-200 dark:hover:bg-slate-800 ${
currentPath === page.path
? 'bg-blue-100 font-semibold dark:bg-blue-900'
: ''
}`}
<li key={page.path}>
<PageLink
path={page.path}
isExpired={Date.now() > page.date.getTime()}
currentPath={currentPath}
>
<h3>{page.title}</h3>
<p className="text-xs text-slate-400">{page.description}</p>
<p className="flex items-center gap-2 text-xs text-slate-500">
<CalendarIcon />{' '}
{formatDate(page.date, ({ MM, DD }) => `${MM}${DD}일`)}
</p>
</Link>
</PageLink>
</li>
) : (
[]
Expand Down Expand Up @@ -151,6 +141,37 @@ const Sidebar = () => {
);
};

const PageLink = ({
children,
path,
isExpired,
currentPath,
}: PropsWithChildren<{
path: string;
isExpired: boolean;
currentPath: string;
}>) => {
const isCurrent = currentPath === path;

return (
<Link
to={path}
ref={(e) => {
if (isCurrent && e !== null) {
e.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
}}
className={cn(
`flex flex-col gap-1 rounded-sm px-4 py-2 transition-colors hover:bg-slate-200 dark:hover:bg-slate-800`,
isCurrent && 'bg-blue-100 font-semibold dark:bg-blue-900',
isExpired && 'opacity-50',
)}
>
{children}
</Link>
);
};

const useTab = () => {
const TAB_KEY = 'tab';

Expand Down
2 changes: 1 addition & 1 deletion frontend/lecture/src/assignments/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactNode } from 'react';
import { type ReactNode } from 'react';

export const getAssignmentItem = (item: {
title: string;
Expand Down
2 changes: 1 addition & 1 deletion frontend/lecture/src/components/Callout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PropsWithChildren } from 'react';
import { type PropsWithChildren } from 'react';

export const Callout = (props: PropsWithChildren<{ title: string }>) => {
return (
Expand Down
2 changes: 1 addition & 1 deletion frontend/lecture/src/components/Description/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Fragment, ReactNode } from 'react';
import { Fragment, type ReactNode } from 'react';

export const Description = ({
items,
Expand Down
2 changes: 1 addition & 1 deletion frontend/lecture/src/components/Illust/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PropsWithChildren } from 'react';
import { type PropsWithChildren } from 'react';

export const Illust = ({ children }: PropsWithChildren) => {
return (
Expand Down
2 changes: 1 addition & 1 deletion frontend/lecture/src/components/SlideLayout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactNode } from 'react';
import { type ReactNode } from 'react';

export const AssetDescriptionLayout = ({
asset: asset,
Expand Down
2 changes: 1 addition & 1 deletion frontend/lecture/src/components/Slides/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactNode, useCallback, useEffect } from 'react';
import { type ReactNode, useCallback, useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';

import {
Expand Down
2 changes: 1 addition & 1 deletion frontend/lecture/src/designsystem/ui/pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from '@radix-ui/react-icons';
import * as React from 'react';

import { ButtonProps, buttonVariants } from '@/designsystem/ui/button';
import { type ButtonProps, buttonVariants } from '@/designsystem/ui/button';
import { cn } from '@/utils/designsystem';

const Pagination = ({ className, ...props }: React.ComponentProps<'nav'>) => (
Expand Down
2 changes: 1 addition & 1 deletion frontend/lecture/src/lectures/Environment/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactNode } from 'react';
import { type ReactNode } from 'react';

import { CodeSnippet } from '@/components/CodeSnippet';
import { ExternalLink } from '@/components/ExternalLink';
Expand Down
2 changes: 1 addition & 1 deletion frontend/lecture/src/lectures/Performance/slides.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC } from 'react';
import { type FC } from 'react';

import { Callout } from '@/components/Callout';
import { CodeSnippet } from '@/components/CodeSnippet';
Expand Down
2 changes: 1 addition & 1 deletion frontend/lecture/src/lectures/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactNode } from 'react';
import { type ReactNode } from 'react';

export const getLectureItem = (item: {
title: string;
Expand Down
2 changes: 1 addition & 1 deletion frontend/lecture/src/pages.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactNode } from 'react';
import { type ReactNode } from 'react';

import { getComoAssignment } from '@/assignments/Como';
import { dataFetchingPracticeAssignment } from '@/assignments/DataFetchingPractice';
Expand Down
80 changes: 79 additions & 1 deletion frontend/lecture/src/pages/home/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,81 @@
import { Link } from 'react-router-dom';

import { pages } from '@/pages';

const getDayTime = (date: Date) => {
const newDate = new Date(date);
newDate.setHours(0, 0, 0, 0);
return newDate.getTime();
};

export const Home = () => {
return <div></div>;
const today = getDayTime(new Date());
const lectures = pages.filter((page) => page.type === 'lecture');
const nextLecture = lectures
.filter((page) => getDayTime(page.date) > today)
.toSorted((p1, p2) => p1.date.getTime() - p2.date.getTime())
.at(0);
const todayLecture = lectures.find((page) => getDayTime(page.date) === today);
const prevLecture = lectures
.filter((page) => getDayTime(page.date) < today)
.toSorted((p1, p2) => p2.date.getTime() - p1.date.getTime())
.at(0);

return (
<div className="flex h-full items-center justify-center">
<div className="grid w-full max-w-screen-md grid-cols-1 gap-8 p-6">
{prevLecture !== undefined && (
<Link
to={prevLecture.path}
className="block rounded-lg bg-white p-4 shadow-md transition duration-300 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700"
>
<h2 className="mb-2 text-xl font-bold text-gray-800 dark:text-gray-200">
이전 세미나
</h2>

<p className="text-blue-600 dark:text-blue-400">
{prevLecture.title}
</p>
<p className="mt-1 text-sm text-gray-600 dark:text-gray-400">
{prevLecture.date.toLocaleDateString()}
</p>
</Link>
)}

{todayLecture !== undefined && (
<Link
to={todayLecture.path}
className="block rounded-lg border-4 border-blue-500 bg-white p-8 shadow-md transition duration-300 hover:bg-gray-100 dark:border-blue-400 dark:bg-gray-800 dark:hover:bg-gray-700"
>
<h2 className="mb-4 text-4xl font-bold text-gray-800 dark:text-gray-200">
오늘의 세미나
</h2>
<p className="text-2xl font-semibold text-blue-600 dark:text-blue-400">
{todayLecture.title}
</p>
<p className="mt-2 text-lg text-gray-600 dark:text-gray-400">
{todayLecture.date.toLocaleDateString()}
</p>
</Link>
)}

{nextLecture !== undefined && (
<Link
to={nextLecture.path}
className="block rounded-lg bg-white p-4 shadow-md transition duration-300 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700"
>
<h2 className="mb-2 text-xl font-bold text-gray-800 dark:text-gray-200">
다음 세미나
</h2>
<p className="text-blue-600 dark:text-blue-400">
{nextLecture.title}
</p>
<p className="mt-1 text-sm text-gray-600 dark:text-gray-400">
{nextLecture.date.toLocaleDateString()}
</p>
</Link>
)}
</div>
</div>
);
};
3 changes: 2 additions & 1 deletion frontend/lecture/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"lib": ["ES2023", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,

Expand All @@ -20,6 +20,7 @@
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"verbatimModuleSyntax": true,

"baseUrl": ".",
"paths": { "@/*": ["./src/*"] }
Expand Down

0 comments on commit 69a97f4

Please sign in to comment.