Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

경기타임 프로젝트 설정 및 HomePage 개발 완료 #89

Merged
merged 9 commits into from
Apr 5, 2024
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
36 changes: 36 additions & 0 deletions apps/time/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
1 change: 1 addition & 0 deletions apps/time/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Time
47 changes: 47 additions & 0 deletions apps/time/app/components/common/Footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Link from 'next/link';
import React from 'react';
import { PATH } from '@constants/path';

const links = [
{
name: '이용약관',
path: PATH.TERMS,
},
{
name: '개인정보처리방침',
path: PATH.PRIVACY,
},
{
name: '동아리운영규칙',
path: PATH.RULES,
},
] as const;

const Footer = () => {
return (
<footer className="p-10 text-center bg-white border-t">
<ul className="flex justify-center text-sm divide-x">
{links.map(({ name, path }) => (
<Link key={name} href={path} className="px-2">
{name}
</Link>
))}
</ul>
<div className="mt-2 text-xs font-medium text-gray-400">
<p className="space-x-1">
<span>Developed By</span>
<a href="https://github.com/KGU-C-Lab" target="_blank">
C-Lab CoreTeam
</a>
<span>X</span>
<a href="https://jinhy.uk" target="_blank">
방진혁
</a>
</p>
<p>© C-Lab. All rights reserved.</p>
</div>
</footer>
);
};

export default Footer;
2 changes: 2 additions & 0 deletions apps/time/app/components/common/Footer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import Footer from './Footer';
export default Footer;
52 changes: 52 additions & 0 deletions apps/time/app/components/common/Nav/Nav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react';
import Link from 'next/link';
import { FiUser } from 'react-icons/fi';
import { PATH } from '@constants/path';

const links = [
<Link key={PATH.HOME} href={PATH.HOME}>
</Link>,
<Link key={PATH.TIMETABLE} href={PATH.TIMETABLE}>
시간표
</Link>,
<Link key={PATH.GRADE} href={PATH.GRADE}>
학점
</Link>,
<Link key={PATH.LIBRARY} href={PATH.LIBRARY}>
도서관
</Link>,
<Link key={PATH.LOST} href={PATH.LOST}>
분실물
</Link>,
<Link key={PATH.LOST} href={PATH.LOST}>
학식
</Link>,
] as const;

const actions = [
<button key={PATH.MY}>
<FiUser size={20} />
</button>,
] as const;

const Nav = () => {
return (
<nav className="fixed top-0 w-full bg-white border-b">
<div className="container flex items-center justify-between h-14 text-nowrap">
<div className="flex items-center gap-2 sm:w-1/5">
<img src="/favicon.ico" alt="c-lab" className="size-8" />
<h1 className="text-xl font-semibold">경기타임</h1>
</div>
<ul className="items-center justify-center hidden w-3/5 gap-4 text-sm sm:flex">
{links.map((link) => link)}
</ul>
<div className="flex items-center justify-end gap-4 text-sm sm:w-1/5">
{actions.map((action) => action)}
</div>
</div>
</nav>
);
};

export default Nav;
2 changes: 2 additions & 0 deletions apps/time/app/components/common/Nav/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import Nav from './Nav';
export default Nav;
30 changes: 30 additions & 0 deletions apps/time/app/components/common/PageLayout/PageLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import Nav from '../Nav';
import Footer from '../Footer';
import { cn } from '@utils/component';

interface PageProps {
nav?: boolean;
footer?: boolean;
className?: string;
children: React.ReactNode;
}

const Page = ({
nav = false,
footer = false,
className,
children,
}: PageProps) => {
return (
<>
{nav && <Nav />}
<main className={cn('max-w-xl m-auto mt-14 p-4', className)}>
{children}
</main>
{footer && <Footer />}
</>
);
};

export default Page;
2 changes: 2 additions & 0 deletions apps/time/app/components/common/PageLayout/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import PageLayout from './PageLayout';
export default PageLayout;
72 changes: 72 additions & 0 deletions apps/time/app/components/home/HomeCard/HomeCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use client';

import { forwardRef, ComponentPropsWithoutRef } from 'react';
import { StrictPropsWithChildren } from '@type/common';
import { cn } from '@utils/component';
import { useRouter } from 'next/navigation';

interface HomeCardProps extends ComponentPropsWithoutRef<'button'> {
to: string;
}

const HomeCard = forwardRef<HTMLButtonElement, HomeCardProps>(
({ to, className, children, ...rest }, ref) => {
const router = useRouter();

return (
<button
ref={ref}
className={cn(
'w-full bg-white border rounded-lg disabled:bg-inherit',
className,
)}
onClick={() => router.push(to)}
{...rest}
>
<div className="flex flex-col h-full p-4 text-left break-keep">
{children}
</div>
</button>
);
},
);
HomeCard.displayName = 'HomeCard';

const HomeCardHeader = forwardRef<HTMLHeadingElement, StrictPropsWithChildren>(
({ children }, ref) => {
return (
<h2 ref={ref} className="mb-2 text-xl font-semibold">
{children}
</h2>
);
},
);
HomeCardHeader.displayName = 'HomeCardHeader';

const HomeCardDescription = forwardRef<
HTMLParagraphElement,
StrictPropsWithChildren
>(({ children }, ref) => {
return (
<p ref={ref} className="text-gray-500">
{children}
</p>
);
});
HomeCardDescription.displayName = 'HomeCardDescription';

const HomeCardIcon = forwardRef<HTMLDivElement, StrictPropsWithChildren>(
({ children }, ref) => {
return (
<div
ref={ref}
className="flex flex-col items-end justify-end h-full mt-2"
>
{children}
</div>
);
},
);
HomeCardIcon.displayName = 'HomeCardIcon';

export { HomeCard, HomeCardHeader, HomeCardDescription, HomeCardIcon };
6 changes: 6 additions & 0 deletions apps/time/app/components/home/HomeCard/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export {
HomeCard,
HomeCardHeader,
HomeCardDescription,
HomeCardIcon,
} from './HomeCard';
15 changes: 15 additions & 0 deletions apps/time/app/constants/path.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export const PATH = {
HOME: '/home',
TIMETABLE: '/timetable',
GRADE: '/grade',
LIBRARY: '/library',
LOST: '/lost',
GRADUATION: '/graduation',
FESTIVAL: '/festival',
FOOD: '/food',
GUIDE: '/guide',
MY: '/my',
TERMS: '/terms',
PRIVACY: '/privacy',
RULES: '/rules',
} as const;
Binary file added apps/time/app/favicon.ico
Binary file not shown.
13 changes: 13 additions & 0 deletions apps/time/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
font-size: 14px;
}

@media (min-width: 768px) {
:root {
font-size: 16px;
}
}
30 changes: 30 additions & 0 deletions apps/time/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { Metadata } from 'next';
import { Noto_Sans_KR } from 'next/font/google';
import { cn } from '@utils/component';
import './globals.css';

const inter = Noto_Sans_KR({ subsets: ['latin'] });

export const metadata: Metadata = {
title: '경기타임',
description: '경기대학교에 계신 모든 순간을 도와드릴게요.',
icons: {
icon: '/favicon.ico',
},
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="ko">
<body
className={cn(inter.className, 'bg-gray-50 min-h-screen flex flex-col')}
>
{children}
</body>
</html>
);
}
Loading