feat(ui): Midnight Glass v2 마감 — lucide 아이콘 통일 + 몰입 패널 웨이브 + 팝업 정합

- @mui/icons-material → lucide-react 전환 (23파일, 잔여 0)
- VoiceRecordingPanel: 9바 DOM 웨이브 → GradientWave (canvas)
- Vanilla 팝업 5종 style.css v2 정합 (글래스 네이비/헤어라인/블루,
  CSS 변수 주입 구조 유지 — 테마 반응형 보존)
This commit is contained in:
Yun Chan 2026-07-21 20:20:32 +09:00
parent a8a1d6e546
commit 082ed2ef02
30 changed files with 212 additions and 289 deletions

View file

@ -4,12 +4,7 @@
import { useState, useEffect, useCallback } from 'react'
import { Box, Button, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, TextField, Chip, Select, MenuItem, FormControl, InputLabel } from '@mui/material'
import AddIcon from '@mui/icons-material/Add'
import DeleteIcon from '@mui/icons-material/Delete'
import EditIcon from '@mui/icons-material/Edit'
import CheckCircleIcon from '@mui/icons-material/CheckCircle'
import PlayArrowIcon from '@mui/icons-material/PlayArrow'
import LinkIcon from '@mui/icons-material/Link'
import { Plus, Trash2, Pencil, CircleCheck, Play, Link } from 'lucide-react'
import { MetalCard, PhosphorText, Led, ScreenPanel } from '@d3ro/ui/components/ds'
import { PageHeader, EmptyStateCard } from '../components/shared'
import { isImeComposingEvent } from '../utils/keyboard'
@ -131,7 +126,7 @@ export function CommandsPage(): React.ReactElement {
title={t('commands.title').toUpperCase()}
count={t('commands.count', { count: instructions.length }).toUpperCase()}
action={
<Button variant="contained" startIcon={<AddIcon />} onClick={openAdd} size="small">
<Button variant="contained" startIcon={<Plus size={16} />} onClick={openAdd} size="small">
{t('commands.add').toUpperCase()}
</Button>
}
@ -183,7 +178,7 @@ export function CommandsPage(): React.ReactElement {
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, flex: 1 }}>
{isActive ? (
<CheckCircleIcon sx={{ fontSize: 16, color: d3roPalette.accent.amber }} />
<CircleCheck size={16} style={{ color: d3roPalette.accent.amber }} />
) : (
<Led color={inst.isBuiltin ? 'amber' : 'green'} size={6} />
)}
@ -210,7 +205,7 @@ export function CommandsPage(): React.ReactElement {
onClick={() => openEdit(inst)}
sx={{ color: d3roPalette.text.inactive, '&:hover': { color: d3roPalette.accent.amber } }}
>
<EditIcon sx={{ fontSize: 16 }} />
<Pencil size={16} />
</IconButton>
{!inst.isBuiltin && (
<IconButton
@ -218,7 +213,7 @@ export function CommandsPage(): React.ReactElement {
onClick={() => handleDelete(inst.id)}
sx={{ color: d3roPalette.text.inactive, '&:hover': { color: d3roPalette.tag.red } }}
>
<DeleteIcon sx={{ fontSize: 16 }} />
<Trash2 size={16} />
</IconButton>
)}
</Box>
@ -360,7 +355,7 @@ function VoiceKeywordsSection({ instructions }: { instructions: CustomInstructio
onClick={() => { setEditingRule(rule.instructionId); setKeywordInput('') }}
sx={{ p: 0.25, color: d3roPalette.text.muted, '&:hover': { color: d3roPalette.accent.amber } }}
>
<AddIcon sx={{ fontSize: 14 }} />
<Plus size={14} />
</IconButton>
)}
</Box>
@ -456,7 +451,7 @@ function ChainSection({ instructions }: { instructions: CustomInstruction[] }):
{t('chain.title').toUpperCase()}
</PhosphorText>
<Box sx={{ flex: 1, height: '1px', bgcolor: d3roPalette.border.subtle }} />
<Button variant="outlined" startIcon={<LinkIcon />} onClick={openAdd} size="small" sx={{ fontSize: d3roTypo.micro.size }}>
<Button variant="outlined" startIcon={<Link size={16} />} onClick={openAdd} size="small" sx={{ fontSize: d3roTypo.micro.size }}>
{t('chain.add').toUpperCase()}
</Button>
</Box>
@ -497,15 +492,15 @@ function ChainSection({ instructions }: { instructions: CustomInstruction[] }):
<Box sx={{ display: 'flex', gap: 0.5 }}>
<IconButton size="small" onClick={() => handleExecute(chain.id)}
sx={{ color: d3roPalette.text.inactive, '&:hover': { color: d3roPalette.tag.green } }}>
<PlayArrowIcon sx={{ fontSize: 16 }} />
<Play size={16} />
</IconButton>
<IconButton size="small" onClick={() => openEdit(chain)}
sx={{ color: d3roPalette.text.inactive, '&:hover': { color: d3roPalette.accent.amber } }}>
<EditIcon sx={{ fontSize: 16 }} />
<Pencil size={16} />
</IconButton>
<IconButton size="small" onClick={() => handleDelete(chain.id)}
sx={{ color: d3roPalette.text.inactive, '&:hover': { color: d3roPalette.tag.red } }}>
<DeleteIcon sx={{ fontSize: 16 }} />
<Trash2 size={16} />
</IconButton>
</Box>
</Box>
@ -563,12 +558,12 @@ function ChainSection({ instructions }: { instructions: CustomInstruction[] }):
)}
<IconButton size="small" onClick={() => removeStep(idx)} disabled={formSteps.length <= 1}
sx={{ color: d3roPalette.text.inactive, '&:hover': { color: d3roPalette.tag.red } }}>
<DeleteIcon sx={{ fontSize: 16 }} />
<Trash2 size={16} />
</IconButton>
</Box>
))}
<Button onClick={addStep} startIcon={<AddIcon />} size="small" sx={{ mt: 1 }}>
<Button onClick={addStep} startIcon={<Plus size={16} />} size="small" sx={{ mt: 1 }}>
{t('chain.addStep')}
</Button>
</DialogContent>