프로토타입 테스트가 가능할 정도의 결재카드 데이터 추가

This commit is contained in:
Kyoung5seo
2026-06-16 22:45:09 +09:00
parent e1f5cafdf1
commit 7f06cb6519
4 changed files with 172 additions and 8 deletions

View File

@@ -1,7 +1,44 @@
import React, { useState, useEffect } from 'react';
import { motion, useMotionValue, useTransform, useAnimation } from 'framer-motion';
import { HandCoins, Droplet, Eye, Shield, Building2, EyeOff } from 'lucide-react';
import './SwipeCard.css';
const renderStats = (stats) => {
if (!stats) return null;
const items = [];
if (stats.res !== 0) items.push({ icon: '✊', label: '저항', val: stats.res, isDanger: true });
if (stats.ent !== 0) items.push({ icon: '🌀', label: '엔트로피', val: stats.ent, isDanger: true });
if (stats.rsk !== 0) items.push({ icon: '⚠️', label: '위험', val: stats.rsk, isDanger: true });
if (stats.bud !== 0) items.push({ icon: <HandCoins size={14} />, label: '예산', val: stats.bud });
if (stats.per !== 0) items.push({ icon: <Droplet size={14} />, label: '인력', val: stats.per });
if (stats.inf !== 0) items.push({ icon: <Eye size={14} />, label: '정보', val: stats.inf });
if (stats.wea !== 0) items.push({ icon: <Building2 size={14} />, label: '재력', val: stats.wea });
if (stats.for !== 0) items.push({ icon: <Shield size={14} />, label: '무력', val: stats.for });
if (stats.sur !== 0) items.push({ icon: <EyeOff size={14} />, label: '감시', val: stats.sur });
if (items.length === 0) return null;
return (
<div className="stats-preview">
{items.map((item, idx) => {
const sign = item.val > 0 ? '+' : '';
const isBad = item.isDanger ? item.val > 0 : item.val < 0;
const colorClass = isBad ? 'stat-bad' : 'stat-good';
return (
<div key={idx} className={`stat-item ${colorClass}`}>
<span className="stat-icon">{item.icon}</span>
<span className="stat-label">{item.label}</span>
<span className="stat-val">{sign}{item.val}</span>
</div>
);
})}
</div>
);
};
export default function SwipeCard({ card, onSwipe, phase }) {
const x = useMotionValue(0);
const controls = useAnimation();
@@ -57,14 +94,21 @@ export default function SwipeCard({ card, onSwipe, phase }) {
<div className="card-body">
<p className="card-text">{card.text}</p>
</div>
{card.flavor && (
<div className="card-flavor-container">
<p className="card-flavor">"{card.flavor}"</p>
</div>
)}
</div>
{/* Swipe Intents */}
<motion.div className="swipe-intent left-intent" style={{ opacity: leftOpacity }}>
<span>{card.left?.text}</span>
<span className="intent-title">{card.left?.text}</span>
{renderStats(card.left?.stats)}
</motion.div>
<motion.div className="swipe-intent right-intent" style={{ opacity: rightOpacity }}>
<span>{card.right?.text}</span>
<span className="intent-title">{card.right?.text}</span>
{renderStats(card.right?.stats)}
</motion.div>
</motion.div>
</div>