chore: ready for work

This commit is contained in:
yoosangwook 2025-04-30 16:47:44 +09:00
parent 17641d2b57
commit 4afcd7f8eb
21 changed files with 1 additions and 525 deletions

View File

@ -1,21 +0,0 @@
'use server'
import { SessionData, sessionOptions } from '@/libs/session'
import { getIronSession } from 'iron-session'
import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'
export const logout = async () => {
const cookieStore = await cookies()
const session = await getIronSession<SessionData>(cookieStore, sessionOptions)
session.destroy()
return redirect('/login')
}
export const getSession = async () => {
const cookieStore = await cookies()
const session = await getIronSession<SessionData>(cookieStore, sessionOptions)
return session
}

View File

@ -1,37 +0,0 @@
import { axiosInstance } from '@/libs/axios'
export interface UserData {
username: string
email: string
password: string
}
export interface User {
id: number
username: string
email: string
created_at: string
updated_at: string
}
export interface LoginData {
username: string
password: string
}
export const userApi = {
create: async (data: UserData): Promise<User> => {
const response = await axiosInstance.post<User>('/api/user/create', data)
return response.data
},
getList: async (): Promise<User[]> => {
const response = await axiosInstance.get<User[]>('/api/user/list')
return response.data
},
getUser: async (data: LoginData): Promise<User> => {
const response = await axiosInstance.post<User>(`/api/user`, data)
return response.data
},
}

View File

@ -1,12 +0,0 @@
import { NextResponse } from 'next/server'
import { prisma } from '@/libs/prisma'
export async function POST(request: Request) {
const body = await request.json()
// @ts-ignore
const suitables = await prisma.MS_SUITABLE.createMany({
data: body,
})
return NextResponse.json({ message: 'Suitable created successfully' })
}

View File

@ -1,23 +0,0 @@
import { NextResponse } from 'next/server'
import { prisma } from '@/libs/prisma'
export async function POST(request: Request) {
try {
const body = await request.json()
const { username, email, password } = body
const user = await prisma.user.create({
data: {
username,
email,
password,
updated_at: new Date(),
},
})
return NextResponse.json(user)
} catch (error) {
console.error('Error creating user:', error)
return NextResponse.json({ error: 'Error creating user' }, { status: 500 })
}
}

View File

@ -1,7 +0,0 @@
import { NextResponse } from 'next/server'
import { prisma } from '@/libs/prisma'
export const GET = async () => {
const users = await prisma.user.findMany()
return NextResponse.json(users)
}

View File

@ -1,37 +0,0 @@
import { NextResponse } from 'next/server'
import { prisma } from '@/libs/prisma'
import { getIronSession } from 'iron-session'
import { cookies } from 'next/headers'
import { SessionData, sessionOptions } from '@/libs/session'
export async function POST(request: Request) {
const { username, password } = await request.json()
console.log('🚀 ~ POST ~ username:', username)
console.log('🚀 ~ POST ~ password:', password)
const user = await prisma.user.findFirst({
where: {
username: username,
password: password,
},
})
console.log('🚀 ~ POST ~ user:', user)
if (!user) {
return NextResponse.json({ error: 'User not found' }, { status: 404 })
}
const cookieStore = await cookies()
const session = await getIronSession<SessionData>(cookieStore, sessionOptions)
console.log('start session edit!')
session.username = user.username!
session.email = user.email!
session.isLoggedIn = true
console.log('end session edit!')
await session.save()
console.log('🚀 ~ POST ~ session:', session)
// return NextResponse.redirect(new URL(process.env.NEXT_PUBLIC_URL!, request.url))
return NextResponse.json(user)
}

View File

@ -1,14 +0,0 @@
import Counter from '@/components/Counter'
export default function page() {
return (
<>
<div className="flex flex-col items-center p-4">
<h1 className="text-4xl font-bold">Counter</h1>
<div className="p-4">
<Counter />
</div>
</div>
</>
)
}

View File

@ -1,26 +0,0 @@
@import "tailwindcss";
:root {
--background: #ffffff;
--foreground: #171717;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
}
body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}

View File

@ -1,18 +1,5 @@
import type { Metadata } from 'next'
import ReactQueryProviders from '@/providers/ReactQueryProvider'
import { Geist, Geist_Mono } from 'next/font/google'
import Footer from '@/components/common/Footer'
import './globals.css'
const geistSans = Geist({
variable: '--font-geist-sans',
subsets: ['latin'],
})
const geistMono = Geist_Mono({
variable: '--font-geist-mono',
subsets: ['latin'],
})
export const metadata: Metadata = {
title: 'Create Next App',
@ -28,7 +15,6 @@ export default function RootLayout({
<html lang="en">
<body>
<ReactQueryProviders>{children}</ReactQueryProviders>
<Footer />
</body>
</html>
)

View File

@ -1,12 +0,0 @@
import Login from '@/components/Login'
export default function page() {
return (
<>
<div className="flex flex-col items-center justify-center h-screen">
<h1 className="text-2xl font-bold">Login</h1>
<Login />
</div>
</>
)
}

View File

@ -1,44 +1,7 @@
import Link from 'next/link'
import User from '@/components/User'
export default async function Home() {
return (
<>
<div className="flex flex-col items-center p-4">
<h1 className="text-4xl font-bold">Index</h1>
<div className="p-4">
<Link href="/counter">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Zustand Counter Example</button>
</Link>
</div>
<div className="p-4">
<Link href="/login">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Session Login Example</button>
</Link>
</div>
<div className="p-4">
<Link href="/suitable">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> </button>
</Link>
</div>
<div className="p-4">
<Link href="/pdf-download">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">PDF </button>
</Link>
</div>
<div className="p-4">
<Link href="/survey-sales">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> </button>
</Link>
</div>
<User />
</div>
<h1> </h1>
</>
)
}

View File

@ -1,10 +0,0 @@
import PdfDownloadNew from '@/components/PdfDownloadNew'
export default function page() {
return (
<>
<h1 className="text-2xl font-bold">PDF </h1>
<PdfDownloadNew />
</>
)
}

View File

@ -1,12 +0,0 @@
import SuitableDetails from '@/components/SuitableDetails'
export default async function page({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params
console.log('🚀 ~ page ~ slug:', slug)
return (
<>
<h1>Suitable Details</h1>
<SuitableDetails roofMaterial={slug} />
</>
)
}

View File

@ -1,13 +0,0 @@
import Suitable from '@/components/Suitable'
import SuitableSearch from '@/components/SuitableSearch'
export default function suitablePage() {
return (
<>
<SuitableSearch />
<Suitable />
{/* 최초 한번 밀어넣음 */}
{/* <SuitableCreateBtn /> */}
</>
)
}

View File

@ -1,31 +0,0 @@
'use client'
import { useCountStore } from '@/store/counter'
export default function Counter() {
const { count, increment, decrement, paramSetting, resetCount } = useCountStore()
return (
<div className="flex gap-2 items-center justify-center flex-col">
<div className="text-2xl">{count}</div>
<div className="flex gap-2">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" onClick={decrement}>
-
</button>
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" onClick={increment}>
+
</button>
</div>
<div className="flex">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" onClick={() => paramSetting({ count: 500 })}>
</button>
</div>
<div className="flex">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" onClick={resetCount}>
</button>
</div>
</div>
)
}

View File

@ -1,79 +0,0 @@
'use client'
import { userApi } from '@/api/user'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { AxiosError } from 'axios'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
export default function Login() {
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [isLogin, setIsLogin] = useState(false)
const router = useRouter()
const { data, error, isPending } = useQuery({
queryKey: ['login-user'],
queryFn: async () => {
try {
const result = await userApi.getUser({ username, password })
router.push('/')
return result
} catch (error: unknown) {
if (error instanceof AxiosError) {
console.log('🚀 ~ handleLogin ~ error:', error.response?.data?.error)
setUsername('')
setPassword('')
setIsLogin(false)
}
throw error
}
},
enabled: isLogin,
retry: false,
staleTime: 0,
})
const handleLogin = async () => {
console.log('🚀 ~ Login ~ username:', username)
console.log('🚀 ~ Login ~ password:', password)
setIsLogin(true)
}
const queryClient = useQueryClient()
const { mutate: createUser } = useMutation({
mutationFn: userApi.create,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['user-list'] })
},
})
return (
<>
<div className="w-full max-w-sm min-w-[200px] m-4">
<input
type="text"
className="w-full bg-transparent placeholder:text-slate-400 text-slate-700 text-sm border border-slate-200 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none focus:border-slate-400 hover:border-slate-300 shadow-sm focus:shadow"
placeholder="Username"
name="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</div>
<div className="w-full max-w-sm min-w-[200px] m-4">
<input
type="password"
className="w-full bg-transparent placeholder:text-slate-400 text-slate-700 text-sm border border-slate-200 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none focus:border-slate-400 hover:border-slate-300 shadow-sm focus:shadow"
placeholder="Password"
name="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" onClick={handleLogin}>
Login
</button>
</>
)
}

View File

@ -1,20 +0,0 @@
'use client'
import { useRef } from 'react'
import generatePDF, { usePDF } from 'react-to-pdf'
export default function PdfDownloadNew() {
const { toPDF, targetRef } = usePDF({ filename: 'page.pdf' })
const myTargetRef = useRef(null)
return (
<div>
<button onClick={() => toPDF()}>Download PDF</button>
<div ref={targetRef}>Content to be generated to PDF</div>
<button onClick={() => generatePDF(myTargetRef, { filename: 'mypage.pdf' })}>Download PDF</button>
<div ref={myTargetRef}>
<h1>Hello</h1>
</div>
</div>
)
}

View File

@ -1,29 +0,0 @@
'use client'
import { suitableApi } from '@/api/suitable'
import { useMutation, useQueryClient } from '@tanstack/react-query'
export default function SuitableCreateBtn() {
const queryClient = useQueryClient()
const {
mutate: createSuitable,
isPending,
error,
} = useMutation({
mutationFn: suitableApi.create,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['suitable-list'] })
},
})
return (
<>
<div>
<button className="bg-blue-500 text-white px-4 py-2 rounded-md" onClick={() => createSuitable()}>
suitable create!!
</button>
</div>
</>
)
}

View File

@ -1,52 +0,0 @@
'use client'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { userApi } from '@/api/user'
import { logout } from '@/api/auth'
import UserList from '@/components/UserList'
export default function User() {
const queryClient = useQueryClient()
const {
mutate: createUser,
isPending,
error,
} = useMutation({
mutationFn: userApi.create,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['user-list'] })
},
})
return (
<>
<div className="p-4">
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
onClick={() => createUser({ username: 'user1', email: 'user1@example.com', password: 'password1' })}
>
User Create1
</button>
</div>
<div className="p-4">
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
onClick={() => createUser({ username: 'user2', email: 'user2@example.com', password: 'password2' })}
>
User Create2
</button>
</div>
<div className="p-4">
{error && <div>Error: {error.message}</div>}
{isPending ? <div>Loading...</div> : <UserList />}
</div>
<div className="p-4">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" onClick={logout}>
Logout
</button>
</div>
</>
)
}

View File

@ -1,25 +0,0 @@
'use client'
import { useQuery } from '@tanstack/react-query'
import { userApi, User } from '@/api/user'
export default function UserList() {
const { data, error, isPending } = useQuery({
queryKey: ['user-list'],
queryFn: userApi.getList,
})
return (
<div>
{isPending && <div>Loading...</div>}
{error && <div>Error: {error.message}</div>}
{data && (
<div>
{data.map((user: User) => (
<div key={user.id}>{user.username}</div>
))}
</div>
)}
</div>
)
}

View File

@ -1,13 +0,0 @@
import Link from 'next/link'
export default function Footer() {
return (
<>
<div className="p-4">
<Link href="/">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">HOME</button>
</Link>
</div>
</>
)
}