mirror of
https://github.com/harivansh-afk/Habit-Tracker.git
synced 2026-04-16 19:04:39 +00:00
Changed backend to work with supabase instead of sqlite
This commit is contained in:
parent
ef8f959f57
commit
f1ca72a782
10 changed files with 362 additions and 784 deletions
|
|
@ -1,14 +1,36 @@
|
|||
import { useState } from 'react';
|
||||
import { supabase } from '../lib/supabase';
|
||||
import { Habit } from '../types';
|
||||
import { calculateStreak } from '../utils/streakCalculator';
|
||||
|
||||
export const useHabits = () => {
|
||||
const [habits, setHabits] = useState<Habit[]>([]);
|
||||
|
||||
const fetchHabits = async () => {
|
||||
try {
|
||||
const response = await fetch('http://localhost:5000/api/habits');
|
||||
const data = await response.json();
|
||||
setHabits(data);
|
||||
const { data, error } = await supabase
|
||||
.from('habits')
|
||||
.select(`
|
||||
id,
|
||||
name,
|
||||
created_at,
|
||||
best_streak,
|
||||
habit_completions (completion_date)
|
||||
`);
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
const formattedHabits = data.map(habit => ({
|
||||
id: habit.id,
|
||||
name: habit.name,
|
||||
created_at: habit.created_at,
|
||||
best_streak: habit.best_streak,
|
||||
completedDates: habit.habit_completions.map(
|
||||
(completion: { completion_date: string }) => completion.completion_date
|
||||
)
|
||||
}));
|
||||
|
||||
setHabits(formattedHabits);
|
||||
} catch (error) {
|
||||
console.error('Error fetching habits:', error);
|
||||
setHabits([]);
|
||||
|
|
@ -17,16 +39,19 @@ export const useHabits = () => {
|
|||
|
||||
const addHabit = async (name: string) => {
|
||||
try {
|
||||
const response = await fetch('http://localhost:5000/api/habits', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name }),
|
||||
});
|
||||
if (response.ok) {
|
||||
await fetchHabits();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
const { error } = await supabase
|
||||
.from('habits')
|
||||
.insert([{
|
||||
name,
|
||||
best_streak: 0,
|
||||
created_at: new Date().toISOString()
|
||||
}])
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (error) throw error;
|
||||
await fetchHabits();
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error adding habit:', error);
|
||||
return false;
|
||||
|
|
@ -35,11 +60,43 @@ export const useHabits = () => {
|
|||
|
||||
const toggleHabit = async (id: number, date: string) => {
|
||||
try {
|
||||
await fetch(`http://localhost:5000/api/habits/${id}/toggle`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ date }),
|
||||
});
|
||||
const { data: existing } = await supabase
|
||||
.from('habit_completions')
|
||||
.select()
|
||||
.eq('habit_id', id)
|
||||
.eq('completion_date', date)
|
||||
.single();
|
||||
|
||||
if (existing) {
|
||||
await supabase
|
||||
.from('habit_completions')
|
||||
.delete()
|
||||
.eq('habit_id', id)
|
||||
.eq('completion_date', date);
|
||||
} else {
|
||||
await supabase
|
||||
.from('habit_completions')
|
||||
.insert([{ habit_id: id, completion_date: date }]);
|
||||
}
|
||||
|
||||
// After toggling, recalculate streak
|
||||
const habit = habits.find(h => h.id === id);
|
||||
if (habit) {
|
||||
const newCompletedDates = existing
|
||||
? habit.completedDates.filter(d => d !== date)
|
||||
: [...habit.completedDates, date];
|
||||
|
||||
const { bestStreak } = calculateStreak(newCompletedDates);
|
||||
|
||||
// Update best_streak if the new streak is higher
|
||||
if (bestStreak > habit.best_streak) {
|
||||
await supabase
|
||||
.from('habits')
|
||||
.update({ best_streak: bestStreak })
|
||||
.eq('id', id);
|
||||
}
|
||||
}
|
||||
|
||||
await fetchHabits();
|
||||
} catch (error) {
|
||||
console.error('Error toggling habit:', error);
|
||||
|
|
@ -48,11 +105,10 @@ export const useHabits = () => {
|
|||
|
||||
const updateHabit = async (id: number, name: string) => {
|
||||
try {
|
||||
await fetch(`http://localhost:5000/api/habits/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name }),
|
||||
});
|
||||
await supabase
|
||||
.from('habits')
|
||||
.update({ name })
|
||||
.eq('id', id);
|
||||
await fetchHabits();
|
||||
} catch (error) {
|
||||
console.error('Error updating habit:', error);
|
||||
|
|
@ -61,39 +117,22 @@ export const useHabits = () => {
|
|||
|
||||
const deleteHabit = async (id: number) => {
|
||||
try {
|
||||
await fetch(`http://localhost:5000/api/habits/${id}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
await supabase
|
||||
.from('habits')
|
||||
.delete()
|
||||
.eq('id', id);
|
||||
await fetchHabits();
|
||||
} catch (error) {
|
||||
console.error('Error deleting habit:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const updateStreak = async (id: number, newStreak: number) => {
|
||||
if (newStreak < 0) return;
|
||||
|
||||
try {
|
||||
await fetch(`http://localhost:5000/api/habits/${id}/streak`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ streak: newStreak }),
|
||||
});
|
||||
setHabits(habits.map(habit =>
|
||||
habit.id === id ? { ...habit, manualStreak: newStreak } : habit
|
||||
));
|
||||
} catch (error) {
|
||||
console.error('Error updating streak:', error);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
habits,
|
||||
fetchHabits,
|
||||
addHabit,
|
||||
toggleHabit,
|
||||
updateHabit,
|
||||
deleteHabit,
|
||||
updateStreak
|
||||
deleteHabit
|
||||
};
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue