banner page
This commit is contained in:
180
src/app/admin/banner/page.tsx
Normal file
180
src/app/admin/banner/page.tsx
Normal file
@@ -0,0 +1,180 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from "react";
|
||||
import AdminSidebar from "@/app/components/AdminSidebar";
|
||||
import BannerRegistrationModal, { type Banner } from "./BannerRegistrationModal";
|
||||
|
||||
export default function AdminBannerPage() {
|
||||
// TODO: 나중에 실제 데이터로 교체
|
||||
const [banners, setBanners] = useState<Banner[]>([
|
||||
{
|
||||
id: 1,
|
||||
order: 1,
|
||||
imageUrl: "http://localhost:3845/assets/43be88ae6f992fc221d0d9c29e82073e7b202f46.png",
|
||||
title: "XR 교육 플랫폼에 오신 것을 환영합니다",
|
||||
description: "다양한 강좌와 함께 성장하는 학습 경험을 시작하세요.",
|
||||
registeredDate: "2025-09-10",
|
||||
},
|
||||
]);
|
||||
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [editingBanner, setEditingBanner] = useState<Banner | null>(null);
|
||||
|
||||
const handleRegister = () => {
|
||||
setEditingBanner(null);
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
|
||||
const handleModalClose = () => {
|
||||
setIsModalOpen(false);
|
||||
setEditingBanner(null);
|
||||
};
|
||||
|
||||
const handleSaveBanner = (title: string, description: string, imageKey?: string) => {
|
||||
// TODO: API가 추가되면 실제로 배너를 저장하고 리스트를 새로고침
|
||||
console.log('배너 저장:', { title, description, imageKey });
|
||||
setIsModalOpen(false);
|
||||
setEditingBanner(null);
|
||||
};
|
||||
|
||||
const handleDeleteBanner = () => {
|
||||
// TODO: API가 추가되면 실제로 배너를 삭제하고 리스트를 새로고침
|
||||
console.log('배너 삭제');
|
||||
setIsModalOpen(false);
|
||||
setEditingBanner(null);
|
||||
};
|
||||
|
||||
const handleRowClick = (banner: Banner) => {
|
||||
setEditingBanner(banner);
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex flex-col bg-white">
|
||||
{/* 메인 레이아웃 */}
|
||||
<div className="flex flex-1 min-h-0 justify-center">
|
||||
<div className="w-[1440px] flex min-h-0">
|
||||
{/* 사이드바 */}
|
||||
<div className="flex">
|
||||
<AdminSidebar />
|
||||
</div>
|
||||
|
||||
{/* 메인 콘텐츠 */}
|
||||
<main className="w-[1120px] bg-white">
|
||||
<div className="h-full flex flex-col px-8">
|
||||
{/* 제목 영역 */}
|
||||
<div className="h-[100px] flex items-center">
|
||||
<h1 className="text-[24px] font-bold leading-[1.5] text-[#1b2027]">
|
||||
배너 관리
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{/* 콘텐츠 영역 */}
|
||||
<div className="flex-1 pt-8 flex flex-col gap-4">
|
||||
{/* 상단 정보 및 버튼 */}
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="text-[15px] font-medium leading-[1.5] text-[#333c47]">
|
||||
총 {banners.length}건
|
||||
</p>
|
||||
<div className="flex gap-3">
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleRegister}
|
||||
className="bg-[#1f2b91] text-white text-[16px] font-semibold leading-[1.5] px-4 py-2 rounded-lg hover:bg-[#1a2478] transition-colors"
|
||||
>
|
||||
등록하기
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 테이블 */}
|
||||
{banners.length === 0 ? (
|
||||
<div className="rounded-lg border border-[#dee1e6] bg-white min-h-[400px] flex items-center justify-center">
|
||||
<p className="text-[16px] font-medium leading-[1.5] text-[#333c47]">
|
||||
현재 관리할 수 있는 항목이 없습니다.
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="border border-[#dee1e6] rounded-lg overflow-hidden">
|
||||
<div className="flex flex-col">
|
||||
{/* 테이블 헤더 */}
|
||||
<div className="bg-gray-50 flex h-12">
|
||||
<div className="border-r border-[#dee1e6] flex items-center justify-center px-4 py-3 shrink-0 w-[57px]">
|
||||
<p className="text-[14px] font-semibold leading-[1.5] text-[#4c5561]">
|
||||
순서
|
||||
</p>
|
||||
</div>
|
||||
<div className="border-r border-[#dee1e6] flex items-center px-4 py-3 shrink-0 w-[240px]">
|
||||
<p className="text-[14px] font-semibold leading-[1.5] text-[#4c5561]">
|
||||
배너 이미지
|
||||
</p>
|
||||
</div>
|
||||
<div className="border-r border-[#dee1e6] flex items-center px-4 py-3 flex-1 min-w-0">
|
||||
<p className="text-[14px] font-semibold leading-[1.5] text-[#4c5561]">
|
||||
배너 문구
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center px-4 py-3 shrink-0 w-[140px]">
|
||||
<p className="text-[14px] font-semibold leading-[1.5] text-[#4c5561]">
|
||||
등록일
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 테이블 바디 */}
|
||||
{banners.map((banner) => (
|
||||
<div
|
||||
key={banner.id}
|
||||
className="border-t border-[#dee1e6] flex cursor-pointer hover:bg-[#F5F7FF] transition-colors"
|
||||
onClick={() => handleRowClick(banner)}
|
||||
>
|
||||
<div className="border-r border-[#dee1e6] flex items-center justify-center px-4 py-3 shrink-0 w-[57px]">
|
||||
<p className="text-[15px] font-medium leading-[1.5] text-[#1b2027]">
|
||||
{banner.order}
|
||||
</p>
|
||||
</div>
|
||||
<div className="border-r border-[#dee1e6] flex items-center justify-center px-4 py-3 shrink-0 w-[240px]">
|
||||
<div className="h-[120px] w-[208px] rounded overflow-hidden">
|
||||
<img
|
||||
src={banner.imageUrl}
|
||||
alt={banner.title}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="border-r border-[#dee1e6] flex items-center px-4 py-3 flex-1 min-w-0">
|
||||
<div className="flex flex-col gap-1">
|
||||
<p className="text-[16px] font-semibold leading-[1.5] text-[#1b2027]">
|
||||
{banner.title}
|
||||
</p>
|
||||
<p className="text-[14px] font-medium leading-[1.5] text-[#333c47]">
|
||||
{banner.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center px-4 py-3 shrink-0 w-[140px]">
|
||||
<p className="text-[15px] font-medium leading-[1.5] text-[#1b2027]">
|
||||
{banner.registeredDate}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
<BannerRegistrationModal
|
||||
open={isModalOpen}
|
||||
onClose={handleModalClose}
|
||||
onSave={handleSaveBanner}
|
||||
onDelete={handleDeleteBanner}
|
||||
editingBanner={editingBanner}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user