Bump app version to 0.2.1 and add Spell and DeleteButton components
- Introduced comprehensive `Spell` models with tagging and state management capabilities. - Added reusable `DeleteButton` component with confirmation workflow for destructive actions.
This commit is contained in:
66
components/form/DeleteButton.tsx
Normal file
66
components/form/DeleteButton.tsx
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
'use client';
|
||||||
|
import {useState} from 'react';
|
||||||
|
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||||
|
import {faTrash} from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import AlertBox from '@/components/AlertBox';
|
||||||
|
|
||||||
|
interface DeleteButtonProps {
|
||||||
|
onDelete: () => void | Promise<void>;
|
||||||
|
confirmTitle: string;
|
||||||
|
confirmMessage: string;
|
||||||
|
confirmButtonText: string;
|
||||||
|
cancelButtonText: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DeleteButton(
|
||||||
|
{
|
||||||
|
onDelete,
|
||||||
|
confirmTitle,
|
||||||
|
confirmMessage,
|
||||||
|
confirmButtonText,
|
||||||
|
cancelButtonText,
|
||||||
|
disabled = false,
|
||||||
|
className = ''
|
||||||
|
}: DeleteButtonProps
|
||||||
|
) {
|
||||||
|
const [showConfirm, setShowConfirm] = useState<boolean>(false);
|
||||||
|
|
||||||
|
function handlePress(): void {
|
||||||
|
if (disabled) return;
|
||||||
|
setShowConfirm(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleConfirm(): Promise<void> {
|
||||||
|
setShowConfirm(false);
|
||||||
|
await onDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCancel(): void {
|
||||||
|
setShowConfirm(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<button
|
||||||
|
onClick={handlePress}
|
||||||
|
disabled={disabled}
|
||||||
|
className={`flex items-center justify-center bg-error/90 hover:bg-error w-10 h-10 rounded-xl border border-error shadow-md hover:shadow-lg hover:scale-110 transition-all duration-200 ${disabled ? 'opacity-50 cursor-not-allowed' : ''} ${className}`}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faTrash} className="text-text-primary w-5 h-5"/>
|
||||||
|
</button>
|
||||||
|
{showConfirm && (
|
||||||
|
<AlertBox
|
||||||
|
title={confirmTitle}
|
||||||
|
message={confirmMessage}
|
||||||
|
type="danger"
|
||||||
|
confirmText={confirmButtonText}
|
||||||
|
cancelText={cancelButtonText}
|
||||||
|
onConfirm={handleConfirm}
|
||||||
|
onCancel={handleCancel}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
109
lib/models/Spell.ts
Normal file
109
lib/models/Spell.ts
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
import {SelectBoxProps} from "@/shared/interface";
|
||||||
|
|
||||||
|
// ==================== SPELL TAG INTERFACES ====================
|
||||||
|
|
||||||
|
export interface SpellTagProps {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
color: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== SPELL INTERFACES ====================
|
||||||
|
|
||||||
|
// Réponse de GET /spell/detail et POST /spell/add
|
||||||
|
export interface SpellProps {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
appearance: string;
|
||||||
|
tags: string[]; // IDs des tags
|
||||||
|
powerLevel: string | null;
|
||||||
|
components: string | null;
|
||||||
|
limitations: string | null;
|
||||||
|
notes: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pour POST /spell/add et PUT /spell/update
|
||||||
|
export interface SpellPropsPost {
|
||||||
|
id?: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
appearance: string;
|
||||||
|
tags: string[];
|
||||||
|
powerLevel?: string | null;
|
||||||
|
components?: string | null;
|
||||||
|
limitations?: string | null;
|
||||||
|
notes?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Item dans la liste (GET /spell/list)
|
||||||
|
export interface SpellListItem {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
tags: SpellTagProps[]; // Tags résolus (pas les IDs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Réponse de GET /spell/list
|
||||||
|
export interface SpellListResponse {
|
||||||
|
enabled: boolean;
|
||||||
|
spells: SpellListItem[];
|
||||||
|
tags: SpellTagProps[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// État local pour l'édition (avec id nullable pour création)
|
||||||
|
export interface SpellEditState {
|
||||||
|
id: string | null;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
appearance: string;
|
||||||
|
tags: string[];
|
||||||
|
powerLevel: string | null;
|
||||||
|
components: string | null;
|
||||||
|
limitations: string | null;
|
||||||
|
notes: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const initialSpellState: SpellEditState = {
|
||||||
|
id: null,
|
||||||
|
name: '',
|
||||||
|
description: '',
|
||||||
|
appearance: '',
|
||||||
|
tags: [],
|
||||||
|
powerLevel: null,
|
||||||
|
components: null,
|
||||||
|
limitations: null,
|
||||||
|
notes: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const spellPowerLevels: SelectBoxProps[] = [
|
||||||
|
{value: 'none', label: 'spellPowerLevels.none'},
|
||||||
|
{value: 'cantrip', label: 'spellPowerLevels.cantrip'},
|
||||||
|
{value: 'novice', label: 'spellPowerLevels.novice'},
|
||||||
|
{value: 'apprentice', label: 'spellPowerLevels.apprentice'},
|
||||||
|
{value: 'journeyman', label: 'spellPowerLevels.journeyman'},
|
||||||
|
{value: 'expert', label: 'spellPowerLevels.expert'},
|
||||||
|
{value: 'master', label: 'spellPowerLevels.master'},
|
||||||
|
{value: 'grandmaster', label: 'spellPowerLevels.grandmaster'},
|
||||||
|
{value: 'legendary', label: 'spellPowerLevels.legendary'},
|
||||||
|
{value: 'divine', label: 'spellPowerLevels.divine'},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const defaultTagColors: string[] = [
|
||||||
|
'#51AE84',
|
||||||
|
'#3A8B69',
|
||||||
|
'#2196F3',
|
||||||
|
'#1976D2',
|
||||||
|
'#FFA726',
|
||||||
|
'#FF9800',
|
||||||
|
'#EF5350',
|
||||||
|
'#E53935',
|
||||||
|
'#AB47BC',
|
||||||
|
'#9C27B0',
|
||||||
|
'#26A69A',
|
||||||
|
'#00897B',
|
||||||
|
'#5C6BC0',
|
||||||
|
'#3F51B5',
|
||||||
|
'#EC407A',
|
||||||
|
'#D81B60',
|
||||||
|
];
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "eritorsscribe",
|
"name": "eritorsscribe",
|
||||||
"productName": "ERitors Scribe",
|
"productName": "ERitors Scribe",
|
||||||
"version": "0.1.1",
|
"version": "0.2.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/electron/main.js",
|
"main": "dist/electron/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Reference in New Issue
Block a user