mirror of
https://github.com/harivansh-afk/Habit-Tracker.git
synced 2026-04-18 07:01:32 +00:00
user settings debugged
This commit is contained in:
parent
1cd3445bd6
commit
20e91dae4c
7 changed files with 282 additions and 224 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Trash2 } from 'lucide-react';
|
||||
import { Habit } from '../types';
|
||||
import { useThemeContext } from '../contexts/ThemeContext';
|
||||
|
|
@ -22,7 +22,15 @@ export function HabitList({
|
|||
onUpdateHabit,
|
||||
onDeleteHabit,
|
||||
}: HabitListProps) {
|
||||
const { showStreaks } = useThemeContext();
|
||||
const { habitSort, showStreaks } = useThemeContext();
|
||||
|
||||
const sortedHabits = useMemo(() => {
|
||||
if (habitSort === 'alphabetical') {
|
||||
return [...habits].sort((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
// Default to dateCreated sort
|
||||
return habits;
|
||||
}, [habits, habitSort]);
|
||||
|
||||
// Helper function to get day name
|
||||
const getDayName = (dateStr: string) => {
|
||||
|
|
@ -53,7 +61,7 @@ export function HabitList({
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{habits.map((habit) => (
|
||||
{sortedHabits.map((habit) => (
|
||||
<tr key={habit.id} className="border-t dark:border-gray-700">
|
||||
<td className="px-4 py-2 dark:text-white">
|
||||
<input
|
||||
|
|
@ -106,6 +114,13 @@ export function HabitList({
|
|||
<Trash2 className="h-4 w-4" />
|
||||
</button>
|
||||
</td>
|
||||
{showStreaks && (
|
||||
<>
|
||||
<td className="px-4 py-2 text-center">
|
||||
{/* ... streak content ... */}
|
||||
</td>
|
||||
</>
|
||||
)}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
|
|
|||
|
|
@ -1,120 +1,95 @@
|
|||
import React from 'react';
|
||||
import { Sun, Moon } from 'lucide-react';
|
||||
import { usePreferences } from '../contexts/PreferencesContext';
|
||||
import { useThemeContext } from '../contexts/ThemeContext';
|
||||
|
||||
export function SettingsView() {
|
||||
const {
|
||||
theme,
|
||||
isDark,
|
||||
showStreaks,
|
||||
dailyReminder,
|
||||
defaultView,
|
||||
habitSort,
|
||||
toggleDarkMode,
|
||||
toggleStreaks,
|
||||
toggleDailyReminder,
|
||||
setDefaultView,
|
||||
setHabitSort
|
||||
} = useThemeContext();
|
||||
const { preferences, updatePreferences } = usePreferences();
|
||||
const { theme } = useThemeContext();
|
||||
|
||||
const handleReminderToggle = () => {
|
||||
if (!dailyReminder && Notification.permission === 'default') {
|
||||
Notification.requestPermission().then(permission => {
|
||||
if (permission === 'granted') {
|
||||
toggleDailyReminder();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
toggleDailyReminder();
|
||||
}
|
||||
const handleThemeChange = async (newTheme: 'light' | 'dark') => {
|
||||
await updatePreferences({ theme: newTheme });
|
||||
// Theme will be updated automatically through ThemeContext
|
||||
};
|
||||
|
||||
const handleSortChange = async (newSort: 'dateCreated' | 'alphabetical') => {
|
||||
await updatePreferences({ habit_sort: newSort });
|
||||
// Sort will be updated automatically through ThemeContext
|
||||
};
|
||||
|
||||
const handleStreaksChange = async (showStreaks: boolean) => {
|
||||
await updatePreferences({ show_streaks: showStreaks });
|
||||
// Streaks visibility will be updated automatically through ThemeContext
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`rounded-lg shadow p-6 ${theme.cardBackground}`}>
|
||||
<h2 className="text-xl font-semibold mb-6 dark:text-white">Settings</h2>
|
||||
|
||||
{/* Theme Toggle */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-2 dark:text-white">Theme</h3>
|
||||
<button
|
||||
onClick={toggleDarkMode}
|
||||
className={`flex items-center space-x-2 px-4 py-2 rounded-lg transition-colors duration-200
|
||||
${isDark
|
||||
? 'bg-gray-700 text-white hover:bg-gray-600'
|
||||
: 'bg-gray-100 text-gray-900 hover:bg-gray-200'}`}
|
||||
>
|
||||
{isDark ? <Moon className="h-5 w-5" /> : <Sun className="h-5 w-5" />}
|
||||
<span>{isDark ? 'Dark Mode' : 'Light Mode'}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Streaks Toggle */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-2 dark:text-white">Streaks</h3>
|
||||
<label className="flex items-center cursor-pointer">
|
||||
<div className="relative">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="sr-only"
|
||||
checked={showStreaks}
|
||||
onChange={toggleStreaks}
|
||||
/>
|
||||
<div className={`w-10 h-6 rounded-full transition-colors duration-200
|
||||
${showStreaks ? 'bg-green-500' : 'bg-gray-300'}`}>
|
||||
<div className={`absolute w-4 h-4 rounded-full bg-white transition-transform duration-200 transform
|
||||
${showStreaks ? 'translate-x-5' : 'translate-x-1'} top-1`} />
|
||||
</div>
|
||||
</div>
|
||||
<span className="ml-3 dark:text-white">Show Streaks</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* Daily Reminder Toggle */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-2 dark:text-white">Notifications</h3>
|
||||
<label className="flex items-center cursor-pointer">
|
||||
<div className="relative">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="sr-only"
|
||||
checked={dailyReminder}
|
||||
onChange={handleReminderToggle}
|
||||
/>
|
||||
<div className={`w-10 h-6 rounded-full transition-colors duration-200
|
||||
${dailyReminder ? 'bg-green-500' : 'bg-gray-300'}`}>
|
||||
<div className={`absolute w-4 h-4 rounded-full bg-white transition-transform duration-200 transform
|
||||
${dailyReminder ? 'translate-x-5' : 'translate-x-1'} top-1`} />
|
||||
</div>
|
||||
</div>
|
||||
<span className="ml-3 dark:text-white">Daily Reminder</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="max-w-2xl mx-auto space-y-8 p-4">
|
||||
{/* Default View */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-2 dark:text-white">Default View</h3>
|
||||
<div className="space-y-2">
|
||||
<h3 className={`text-lg font-medium ${theme.text}`}>Default View</h3>
|
||||
<select
|
||||
value={defaultView}
|
||||
onChange={(e) => setDefaultView(e.target.value as 'habits' | 'calendar')}
|
||||
className="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 sm:text-sm rounded-md dark:bg-gray-700 dark:border-gray-600 dark:text-white"
|
||||
value={preferences.default_view}
|
||||
onChange={(e) => updatePreferences({ default_view: e.target.value as 'habits' | 'calendar' })}
|
||||
className={`w-full p-2 rounded-lg border ${theme.input}`}
|
||||
>
|
||||
<option value="habits">Habits</option>
|
||||
<option value="calendar">Calendar</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Habit Sort */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-2 dark:text-white">Sort Habits By</h3>
|
||||
{/* Sort Habits */}
|
||||
<div className="space-y-2">
|
||||
<h3 className={`text-lg font-medium ${theme.text}`}>Sort Habits By</h3>
|
||||
<select
|
||||
value={habitSort}
|
||||
onChange={(e) => setHabitSort(e.target.value as 'dateCreated' | 'alphabetical')}
|
||||
className="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 sm:text-sm rounded-md dark:bg-gray-700 dark:border-gray-600 dark:text-white"
|
||||
value={preferences.habit_sort}
|
||||
onChange={(e) => handleSortChange(e.target.value as 'dateCreated' | 'alphabetical')}
|
||||
className={`w-full p-2 rounded-lg border ${theme.input}`}
|
||||
>
|
||||
<option value="dateCreated">Date Created</option>
|
||||
<option value="alphabetical">Alphabetical</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Show Streaks */}
|
||||
<div className="space-y-2">
|
||||
<h3 className={`text-lg font-medium ${theme.text}`}>Show Streaks</h3>
|
||||
<label className="flex items-center space-x-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={preferences.show_streaks}
|
||||
onChange={(e) => handleStreaksChange(e.target.checked)}
|
||||
className="form-checkbox h-5 w-5 text-green-500"
|
||||
/>
|
||||
<span className={theme.text}>Enable streak counting</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* Daily Reminder */}
|
||||
<div className="space-y-2">
|
||||
<h3 className={`text-lg font-medium ${theme.text}`}>Daily Reminder</h3>
|
||||
<label className="flex items-center space-x-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={preferences.daily_reminder}
|
||||
onChange={(e) => updatePreferences({ daily_reminder: e.target.checked })}
|
||||
className="form-checkbox h-5 w-5 text-green-500"
|
||||
/>
|
||||
<span className={theme.text}>Enable daily reminders</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* Theme */}
|
||||
<div className="space-y-2">
|
||||
<h3 className={`text-lg font-medium ${theme.text}`}>Theme</h3>
|
||||
<select
|
||||
value={preferences.theme}
|
||||
onChange={(e) => handleThemeChange(e.target.value as 'light' | 'dark')}
|
||||
className={`w-full p-2 rounded-lg border ${theme.input}`}
|
||||
>
|
||||
<option value="light">Light</option>
|
||||
<option value="dark">Dark</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue