initial commit

This commit is contained in:
2026-01-31 22:34:57 +09:00
commit f1301de543
875 changed files with 196598 additions and 0 deletions

103
components/CommonUI.tsx Normal file
View File

@@ -0,0 +1,103 @@
import React from 'react';
// --- StatCard: 대시보드 및 자산 요약용 ---
interface StatCardProps {
title: string;
value: string;
change?: string;
isUp?: boolean;
icon: React.ReactNode;
}
export const StatCard: React.FC<StatCardProps> = ({ title, value, change, isUp, icon }) => (
<div className="bg-white p-8 rounded-[3rem] shadow-sm border border-slate-100 flex items-start justify-between group hover:border-blue-100 transition-all">
<div>
<p className="text-[11px] font-black text-slate-400 mb-3 uppercase tracking-widest">{title}</p>
<h4 className="text-2xl font-black text-slate-900 leading-none">{value}</h4>
{change && (
<p className={`text-[11px] font-black mt-4 flex items-center gap-2 ${isUp ? 'text-emerald-500' : 'text-rose-500'}`}>
{change}
</p>
)}
</div>
<div className="bg-slate-50 p-5 rounded-3xl group-hover:bg-blue-50 transition-colors">
{icon}
</div>
</div>
);
// --- FilterChip: 시장/정렬/카테고리 필터용 ---
interface FilterChipProps {
active: boolean;
onClick: () => void;
label: string;
}
export const FilterChip: React.FC<FilterChipProps> = ({ active, onClick, label }) => (
<button
onClick={onClick}
className={`px-5 py-2 rounded-full text-[12px] font-black transition-all ${active ? 'bg-slate-900 text-white shadow-lg' : 'bg-slate-100 text-slate-500 hover:bg-slate-200'}`}
>
{label}
</button>
);
// --- TabButton: 대분류 섹션 전환용 ---
interface TabButtonProps {
active: boolean;
onClick: () => void;
icon: React.ReactNode;
label: string;
}
export const TabButton: React.FC<TabButtonProps> = ({ active, onClick, icon, label }) => (
<button
onClick={onClick}
className={`flex items-center gap-3 pb-4 whitespace-nowrap transition-all border-b-2 ${active ? 'border-blue-600 text-blue-600 font-black' : 'border-transparent text-slate-400 font-bold hover:text-slate-600'}`}
>
{icon}
<span className="text-base tracking-tight">{label}</span>
</button>
);
// --- InputGroup: 설정창 및 폼 입력용 ---
interface InputGroupProps {
label: string;
value: string;
onChange: (v: string) => void;
placeholder: string;
type?: string;
icon?: React.ReactNode;
}
export const InputGroup: React.FC<InputGroupProps> = ({ label, value, onChange, placeholder, type = "text", icon }) => (
<div className="space-y-3">
<label className="text-[11px] font-black text-slate-400 uppercase tracking-widest block pl-1 flex items-center gap-2">
{icon} {label}
</label>
<input
type={type}
value={value}
onChange={(e) => onChange(e.target.value)}
className="w-full p-4 bg-slate-50 border border-slate-200 rounded-[1.2rem] focus:border-blue-500 focus:bg-white outline-none transition-all font-bold text-slate-800 placeholder:text-slate-300 shadow-sm"
placeholder={placeholder}
/>
</div>
);
// --- ToggleButton: 활성화/비활성 스위치 ---
interface ToggleButtonProps {
active: boolean;
onClick: () => void;
}
export const ToggleButton: React.FC<ToggleButtonProps> = ({ active, onClick }) => (
<button
type="button"
onClick={onClick}
className={`relative inline-flex h-8 w-14 items-center rounded-full transition-all focus:outline-none ${active ? 'bg-emerald-500' : 'bg-slate-300'}`}
>
<span className={`inline-block h-5 w-5 transform rounded-full bg-white transition-transform ${active ? 'translate-x-7' : 'translate-x-2'}`} />
</button>
);