init
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
import { supabase } from './supabase';
|
||||
import * as offline from './offlineStorage';
|
||||
import { generateHabitsFromIdentity } from '../utils/helpers';
|
||||
import { todayISO, addDays } from '../utils/date';
|
||||
|
||||
// Must match authService.js
|
||||
const USE_OFFLINE = true;
|
||||
|
||||
// ========================
|
||||
// GET IDENTITY
|
||||
// ========================
|
||||
export async function getIdentity(userId) {
|
||||
if (USE_OFFLINE) {
|
||||
return offline.getOne('identities', { user_id: userId });
|
||||
}
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('identities')
|
||||
.select('*')
|
||||
.eq('user_id', userId)
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
if (error && error.code !== 'PGRST116') throw error;
|
||||
return data || null;
|
||||
}
|
||||
|
||||
// ========================
|
||||
// CREATE IDENTITY
|
||||
// ========================
|
||||
export async function createIdentity(userId, title, description, customHabits, storyText) {
|
||||
const startDate = todayISO();
|
||||
const endDate = addDays(new Date(), 40);
|
||||
|
||||
if (USE_OFFLINE) {
|
||||
const identity = await offline.insert('identities', {
|
||||
user_id: userId,
|
||||
title,
|
||||
description: description || title,
|
||||
story_text: storyText || '',
|
||||
start_date: startDate,
|
||||
end_date: endDate,
|
||||
status: 'active',
|
||||
});
|
||||
|
||||
const habitsList = customHabits && customHabits.length > 0
|
||||
? customHabits
|
||||
: generateHabitsFromIdentity(title);
|
||||
|
||||
const habitsToInsert = habitsList.map((h) => ({
|
||||
identity_id: identity.id,
|
||||
title: h.title,
|
||||
description: h.description || '',
|
||||
}));
|
||||
|
||||
const habits = await offline.insertMany('habits', habitsToInsert);
|
||||
|
||||
await offline.insert('stats', {
|
||||
identity_id: identity.id,
|
||||
discipline_score: 0,
|
||||
focus_score: 0,
|
||||
consistency_score: 0,
|
||||
});
|
||||
|
||||
return { identity, habits };
|
||||
}
|
||||
|
||||
// --- Supabase path ---
|
||||
const { data, error } = await supabase
|
||||
.from('identities')
|
||||
.insert({
|
||||
user_id: userId,
|
||||
title,
|
||||
description: description || title,
|
||||
story_text: storyText || '',
|
||||
start_date: startDate,
|
||||
end_date: endDate,
|
||||
status: 'active',
|
||||
})
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
const habitsList = customHabits && customHabits.length > 0
|
||||
? customHabits
|
||||
: generateHabitsFromIdentity(title);
|
||||
|
||||
const habitsToInsert = habitsList.map((h) => ({
|
||||
identity_id: data.id,
|
||||
title: h.title,
|
||||
description: h.description || '',
|
||||
}));
|
||||
|
||||
const { data: habits, error: habitsError } = await supabase
|
||||
.from('habits')
|
||||
.insert(habitsToInsert)
|
||||
.select();
|
||||
|
||||
if (habitsError) throw habitsError;
|
||||
|
||||
await supabase.from('stats').insert({
|
||||
identity_id: data.id,
|
||||
discipline_score: 0,
|
||||
focus_score: 0,
|
||||
consistency_score: 0,
|
||||
});
|
||||
|
||||
return { identity: data, habits: habits || [] };
|
||||
}
|
||||
|
||||
// ========================
|
||||
// DAILY LOGS
|
||||
// ========================
|
||||
export async function getDailyLogs(identityId) {
|
||||
if (USE_OFFLINE) {
|
||||
const logs = await offline.getAll('daily_logs', { identity_id: identityId });
|
||||
return logs.sort((a, b) => a.day_number - b.day_number);
|
||||
}
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('daily_logs')
|
||||
.select('*')
|
||||
.eq('identity_id', identityId)
|
||||
.order('day_number', { ascending: true });
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
}
|
||||
|
||||
export async function saveDailyLog(identityId, dayNumber, identityCheck, note) {
|
||||
const today = todayISO();
|
||||
|
||||
if (USE_OFFLINE) {
|
||||
await offline.upsert(
|
||||
'daily_logs',
|
||||
{ identity_id: identityId, date: today },
|
||||
{ day_number: dayNumber, identity_check: identityCheck, note: note || '' }
|
||||
);
|
||||
|
||||
// Update stats
|
||||
const scoreAdd = identityCheck === 'yes' ? 3 : identityCheck === 'almost' ? 1 : 0;
|
||||
if (scoreAdd > 0) {
|
||||
const stats = await offline.getOne('stats', { identity_id: identityId });
|
||||
if (stats) {
|
||||
await offline.update('stats', { id: stats.id }, {
|
||||
discipline_score: stats.discipline_score + scoreAdd,
|
||||
consistency_score: stats.consistency_score + (identityCheck === 'yes' ? 2 : 1),
|
||||
focus_score: stats.focus_score + scoreAdd,
|
||||
});
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// --- Supabase path ---
|
||||
const { data: existing } = await supabase
|
||||
.from('daily_logs')
|
||||
.select('id')
|
||||
.eq('identity_id', identityId)
|
||||
.eq('date', today)
|
||||
.maybeSingle();
|
||||
|
||||
if (existing) {
|
||||
const { error } = await supabase
|
||||
.from('daily_logs')
|
||||
.update({ identity_check: identityCheck, note: note || '' })
|
||||
.eq('id', existing.id);
|
||||
if (error) throw error;
|
||||
} else {
|
||||
const { error } = await supabase
|
||||
.from('daily_logs')
|
||||
.insert({
|
||||
identity_id: identityId,
|
||||
date: today,
|
||||
day_number: dayNumber,
|
||||
identity_check: identityCheck,
|
||||
note: note || '',
|
||||
});
|
||||
if (error) throw error;
|
||||
}
|
||||
|
||||
const scoreAdd = identityCheck === 'yes' ? 3 : identityCheck === 'almost' ? 1 : 0;
|
||||
if (scoreAdd > 0) {
|
||||
const { data: stats } = await supabase
|
||||
.from('stats')
|
||||
.select('*')
|
||||
.eq('identity_id', identityId)
|
||||
.maybeSingle();
|
||||
|
||||
if (stats) {
|
||||
await supabase
|
||||
.from('stats')
|
||||
.update({
|
||||
discipline_score: stats.discipline_score + scoreAdd,
|
||||
consistency_score: stats.consistency_score + (identityCheck === 'yes' ? 2 : 1),
|
||||
focus_score: stats.focus_score + scoreAdd,
|
||||
})
|
||||
.eq('id', stats.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========================
|
||||
// STATS
|
||||
// ========================
|
||||
export async function getStats(identityId) {
|
||||
if (USE_OFFLINE) {
|
||||
return offline.getOne('stats', { identity_id: identityId });
|
||||
}
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('stats')
|
||||
.select('*')
|
||||
.eq('identity_id', identityId)
|
||||
.single();
|
||||
|
||||
if (error && error.code !== 'PGRST116') throw error;
|
||||
return data || null;
|
||||
}
|
||||
|
||||
// ========================
|
||||
// GAME SESSIONS
|
||||
// ========================
|
||||
export async function saveGameScore(identityId, gameType, score) {
|
||||
if (USE_OFFLINE) {
|
||||
await offline.insert('game_sessions', {
|
||||
identity_id: identityId,
|
||||
game_type: gameType,
|
||||
score,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const { error } = await supabase.from('game_sessions').insert({
|
||||
identity_id: identityId,
|
||||
game_type: gameType,
|
||||
score,
|
||||
});
|
||||
if (error) throw error;
|
||||
}
|
||||
Reference in New Issue
Block a user