Files
ERitors-Scribe-Desktop/components/book/settings/goals/page.tsx
natreex c9cf99e166 Update imports and Electron compatibility
- Removed unnecessary React imports.
- Adjusted package.json scripts for Electron integration.
- Updated components to replace Next.js-specific imports with Electron-compatible alternatives.
- Minor tsconfig.json changes for better compatibility.
2025-11-16 11:55:52 -05:00

182 lines
8.9 KiB
TypeScript

'use client'
import {useState} from 'react';
interface TimeGoal {
desiredReleaseDate: string;
maxReleaseDate: string;
}
interface NumbersGoal {
minWordsCount: number;
maxWordsCount: number;
desiredWordsCountByChapter: number;
desiredChapterCount: number;
}
interface Goal {
id: number;
name: string;
timeGoal: TimeGoal;
numbersGoal: NumbersGoal;
}
export default function GoalsPage() {
const [goals, setGoals] = useState<Goal[]>([
{
id: 1,
name: 'First Goal',
timeGoal: {
desiredReleaseDate: '',
maxReleaseDate: '',
},
numbersGoal: {
minWordsCount: 0,
maxWordsCount: 0,
desiredWordsCountByChapter: 0,
desiredChapterCount: 0,
},
},
]);
const [selectedGoalIndex, setSelectedGoalIndex] = useState(0);
const [newGoalName, setNewGoalName] = useState('');
const handleAddGoal = () => {
const newGoal: Goal = {
id: goals.length + 1,
name: newGoalName,
timeGoal: {
desiredReleaseDate: '',
maxReleaseDate: '',
},
numbersGoal: {
minWordsCount: 0,
maxWordsCount: 0,
desiredWordsCountByChapter: 0,
desiredChapterCount: 0,
},
};
setGoals([...goals, newGoal]);
setNewGoalName('');
};
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>, field: keyof Goal, subField?: keyof TimeGoal | keyof NumbersGoal) => {
const updatedGoals = [...goals];
if (subField) {
if (field === 'timeGoal' && subField in updatedGoals[selectedGoalIndex].timeGoal) {
(updatedGoals[selectedGoalIndex].timeGoal[subField as keyof TimeGoal] as string) = e.target.value;
} else if (field === 'numbersGoal' && subField in updatedGoals[selectedGoalIndex].numbersGoal) {
(updatedGoals[selectedGoalIndex].numbersGoal[subField as keyof NumbersGoal] as number) = Number(e.target.value);
}
} else {
(updatedGoals[selectedGoalIndex][field] as string) = e.target.value;
}
setGoals(updatedGoals);
};
return (
<main className="flex-grow p-8 overflow-y-auto">
<section id="goals">
<h2 className="text-4xl font-['ADLaM_Display'] text-text-primary mb-6">Goals</h2>
<div className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-6 shadow-lg mb-6">
<div className="flex space-x-4 items-center">
<select
className="w-full px-4 py-2.5 rounded-xl bg-secondary/50 text-text-primary border border-secondary/50 outline-none hover:bg-secondary hover:border-secondary focus:border-primary focus:ring-4 focus:ring-primary/20 transition-all duration-200"
value={selectedGoalIndex}
onChange={(e) => setSelectedGoalIndex(parseInt(e.target.value))}
>
{goals.map((goal, index) => (
<option key={goal.id} value={index}>{goal.name}</option>
))}
</select>
<input
type="text"
value={newGoalName}
onChange={(e) => setNewGoalName(e.target.value)}
className="w-full px-4 py-2.5 rounded-xl bg-secondary/50 text-text-primary border border-secondary/50 outline-none hover:bg-secondary hover:border-secondary focus:border-primary focus:ring-4 focus:ring-primary/20 transition-all duration-200"
placeholder="New Goal Name"
/>
<button
type="button"
onClick={handleAddGoal}
className="bg-primary hover:bg-primary-dark text-text-primary font-semibold py-2.5 px-5 rounded-xl shadow-md hover:shadow-lg hover:scale-105 transition-all duration-200"
>
Add Goal
</button>
</div>
</div>
<h2 className="text-3xl font-['ADLaM_Display'] text-text-primary mb-6">{goals[selectedGoalIndex].name}</h2>
<div className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-6 shadow-lg mb-6">
<h3 className="text-2xl font-bold text-text-primary mb-4">Time Goal</h3>
<label className="block text-text-primary font-medium mb-2" htmlFor="desiredReleaseDate">Desired
Release Date</label>
<input
type="date"
id="desiredReleaseDate"
value={goals[selectedGoalIndex].timeGoal.desiredReleaseDate}
onChange={(e) => handleInputChange(e, 'timeGoal', 'desiredReleaseDate')}
className="w-full p-2 rounded-lg bg-gray-800 text-white border-none outline-none"
/>
<label className="block text-white mb-2 mt-4" htmlFor="maxReleaseDate">Max Release Date</label>
<input
type="date"
id="maxReleaseDate"
value={goals[selectedGoalIndex].timeGoal.maxReleaseDate}
onChange={(e) => handleInputChange(e, 'timeGoal', 'maxReleaseDate')}
className="w-full p-2 rounded-lg bg-gray-800 text-white border-none outline-none"
/>
</div>
<div className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-6 shadow-lg mb-6">
<h3 className="text-2xl font-bold text-text-primary mb-4">Numbers Goal</h3>
<label className="block text-text-primary font-medium mb-2" htmlFor="minWordsCount">Min Words
Count</label>
<input
type="number"
id="minWordsCount"
value={goals[selectedGoalIndex].numbersGoal.minWordsCount}
onChange={(e) => handleInputChange(e, 'numbersGoal', 'minWordsCount')}
className="w-full p-2 rounded-lg bg-gray-800 text-white border-none outline-none"
/>
<label className="block text-white mb-2 mt-4" htmlFor="maxWordsCount">Max Words Count</label>
<input
type="number"
id="maxWordsCount"
value={goals[selectedGoalIndex].numbersGoal.maxWordsCount}
onChange={(e) => handleInputChange(e, 'numbersGoal', 'maxWordsCount')}
className="w-full p-2 rounded-lg bg-gray-800 text-white border-none outline-none"
/>
<label className="block text-white mb-2 mt-4" htmlFor="desiredWordsCountByChapter">Desired Words
Count by Chapter</label>
<input
type="number"
id="desiredWordsCountByChapter"
value={goals[selectedGoalIndex].numbersGoal.desiredWordsCountByChapter}
onChange={(e) => handleInputChange(e, 'numbersGoal', 'desiredWordsCountByChapter')}
className="w-full p-2 rounded-lg bg-gray-800 text-white border-none outline-none"
/>
<label className="block text-white mb-2 mt-4" htmlFor="desiredChapterCount">Desired Chapter
Count</label>
<input
type="number"
id="desiredChapterCount"
value={goals[selectedGoalIndex].numbersGoal.desiredChapterCount}
onChange={(e) => handleInputChange(e, 'numbersGoal', 'desiredChapterCount')}
className="w-full p-2 rounded-lg bg-gray-800 text-white border-none outline-none"
/>
</div>
<div className="text-center mt-8">
<button
type="button"
className="bg-primary hover:bg-primary-dark text-text-primary font-semibold py-2.5 px-6 rounded-xl shadow-md hover:shadow-lg hover:scale-105 transition-all duration-200"
>
Update
</button>
</div>
</section>
</main>
);
}