diff --git a/frontend/src/pages/pc/admin/AdminScheduleDict.jsx b/frontend/src/pages/pc/admin/AdminScheduleDict.jsx index 59175ff..5338ea9 100644 --- a/frontend/src/pages/pc/admin/AdminScheduleDict.jsx +++ b/frontend/src/pages/pc/admin/AdminScheduleDict.jsx @@ -9,6 +9,35 @@ import useAdminAuth from '../../../hooks/useAdminAuth'; import useToast from '../../../hooks/useToast'; import * as suggestionsApi from '../../../api/admin/suggestions'; +// 애니메이션 variants +const containerVariants = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.08, + }, + }, +}; + +const itemVariants = { + hidden: { opacity: 0, y: 20 }, + visible: { + opacity: 1, + y: 0, + transition: { duration: 0.4, ease: "easeOut" }, + }, +}; + +const cardVariants = { + hidden: { opacity: 0, scale: 0.95 }, + visible: { + opacity: 1, + scale: 1, + transition: { duration: 0.3, ease: "easeOut" }, + }, +}; + // 품사 태그 옵션 const POS_TAGS = [ { value: 'NNP', label: '고유명사 (NNP)', description: '사람, 그룹, 프로그램 이름 등', examples: '프로미스나인, 송하영, 뮤직뱅크' }, @@ -403,9 +432,14 @@ function AdminScheduleDict() { /> {/* 메인 콘텐츠 */} -
+ {/* 브레드크럼 */} -
+ @@ -415,36 +449,36 @@ function AdminScheduleDict() { 사전 관리 -
+
{/* 타이틀 */} -
+

사전 관리

형태소 분석기 사용자 사전을 관리합니다

-
+ {/* 통계 카드 */} -
-
+ +
{posStats.total || 0}
전체 단어
-
-
+ +
{posStats.NNP || 0}
고유명사
-
-
+ +
{posStats.NNG || 0}
일반명사
-
-
+ +
{posStats.SL || 0}
외국어
-
-
+ + {/* 단어 추가 영역 */} -
+

단어 추가

@@ -502,10 +536,10 @@ function AdminScheduleDict() { 추가
-
+
{/* 단어 목록 */} -
+ {/* 검색 및 필터 */}
@@ -616,8 +650,8 @@ function AdminScheduleDict() { )}
)} -
-
+ + ); } diff --git a/frontend/src/pages/pc/admin/schedule/form/index.jsx b/frontend/src/pages/pc/admin/schedule/form/index.jsx index bee2b4b..133fa5f 100644 --- a/frontend/src/pages/pc/admin/schedule/form/index.jsx +++ b/frontend/src/pages/pc/admin/schedule/form/index.jsx @@ -1,5 +1,6 @@ import { useState, useEffect } from "react"; import { useNavigate, Link } from "react-router-dom"; +import { motion, AnimatePresence } from "framer-motion"; import { Home, ChevronRight } from "lucide-react"; import AdminLayout from "../../../../../components/admin/AdminLayout"; import useAdminAuth from "../../../../../hooks/useAdminAuth"; @@ -8,6 +9,40 @@ import CategorySelector from "./components/CategorySelector"; import YouTubeForm from "./YouTubeForm"; import XForm from "./XForm"; +// 애니메이션 variants +const containerVariants = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.1, + }, + }, +}; + +const itemVariants = { + hidden: { opacity: 0, y: 20 }, + visible: { + opacity: 1, + y: 0, + transition: { duration: 0.4, ease: "easeOut" }, + }, +}; + +const formVariants = { + hidden: { opacity: 0, y: 20 }, + visible: { + opacity: 1, + y: 0, + transition: { duration: 0.3, ease: "easeOut" }, + }, + exit: { + opacity: 0, + y: -10, + transition: { duration: 0.2 }, + }, +}; + // 카테고리 ID 상수 const CATEGORY_IDS = { YOUTUBE: 2, @@ -86,9 +121,17 @@ function ScheduleFormPage() { return ( -
+ {/* 브레드크럼 */} -
+ 일정 추가 -
+
{/* 타이틀 */} -
+

일정 추가

카테고리를 선택하고 일정을 등록하세요

-
+ {/* 카테고리 선택 */} -
+ -
+ {/* 카테고리별 폼 */} - {renderForm()} -
+ + + {renderForm()} + + +
); }