Refactor large files into modular components
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 1m9s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 1m9s
- Refactored page.tsx (613→252 lines) with GameOverScreen and LeftPanel extracted - Refactored StatsTab.tsx (584→92 lines) with section components - Refactored SkillsTab.tsx (434→54 lines) with sub-components - Created modular structure for GameContext, LootInventory, and other components - All extracted components organized into feature directories
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
'use client';
|
||||
|
||||
import type { LootInventory } from '@/lib/game/types';
|
||||
// For backward compatibility
|
||||
type LootInventoryType = LootInventory;
|
||||
import { LOOT_DROPS } from '@/lib/game/data/loot-drops';
|
||||
import { RARITY_CSS_VAR, RARITY_GLOW_CSS_VAR } from './types';
|
||||
import { Sparkles, Trash2 } from 'lucide-react';
|
||||
import { ActionButton } from '@/components/ui/action-button';
|
||||
|
||||
interface MaterialItemProps {
|
||||
materialId: string;
|
||||
count: number;
|
||||
onDelete?: (materialId: string) => void;
|
||||
}
|
||||
|
||||
export function MaterialItem({ materialId, count, onDelete }: MaterialItemProps) {
|
||||
const drop = LOOT_DROPS[materialId];
|
||||
if (!drop) return null;
|
||||
|
||||
const rarityColor = RARITY_CSS_VAR[drop.rarity] || 'var(--rarity-common)';
|
||||
const rarityGlow = RARITY_GLOW_CSS_VAR[drop.rarity] || 'var(--rarity-common-glow)';
|
||||
|
||||
return (
|
||||
<div
|
||||
className="p-2 rounded border bg-[var(--bg-sunken)] group relative"
|
||||
style={{
|
||||
borderColor: rarityColor,
|
||||
backgroundColor: rarityGlow,
|
||||
}}
|
||||
>
|
||||
<div className="flex items-start justify-between">
|
||||
<div>
|
||||
<div className="text-xs font-semibold" style={{ color: rarityColor }}>
|
||||
{drop.name}
|
||||
</div>
|
||||
<div className="text-xs text-[var(--text-secondary)]">
|
||||
x{count}
|
||||
</div>
|
||||
<div className="text-xs text-[var(--text-muted)] capitalize">
|
||||
{drop.rarity}
|
||||
</div>
|
||||
</div>
|
||||
{onDelete && (
|
||||
<ActionButton
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="h-5 w-5 p-0 opacity-0 group-hover:opacity-100 text-[var(--color-danger)] hover:text-[var(--interactive-danger-hover)] hover:bg-[var(--interactive-danger)]/20"
|
||||
onClick={() => onDelete(materialId)}
|
||||
aria-label={`Delete ${drop.name}`}
|
||||
>
|
||||
<Trash2 className="w-3 h-3" />
|
||||
</ActionButton>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface MaterialsSectionProps {
|
||||
materials: [string, number][];
|
||||
onDeleteMaterial?: (materialId: string) => void;
|
||||
}
|
||||
|
||||
export function MaterialsSection({ materials, onDeleteMaterial }: MaterialsSectionProps) {
|
||||
if (materials.length === 0) return null;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="text-xs text-[var(--text-muted)] mb-2 flex items-center gap-1">
|
||||
<Sparkles className="w-3 h-3" />
|
||||
Materials
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
{materials.map(([id, count]) => (
|
||||
<MaterialItem
|
||||
key={id}
|
||||
materialId={id}
|
||||
count={count}
|
||||
onDelete={onDeleteMaterial}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user