133 lines
4.6 KiB
TypeScript
133 lines
4.6 KiB
TypeScript
import { JobApplication, UserProfile, NotificationLog, CalendarInterviewEvent } from '../types';
|
|
|
|
export const isFirebaseConfigured = false;
|
|
|
|
// 100% Pure Local Disk & LocalStorage Persistence System
|
|
|
|
const STORAGE_KEYS = {
|
|
APPLICATIONS: 'ai_job_portal_applications',
|
|
USER_PROFILE: 'ai_job_portal_profile',
|
|
NOTIFICATIONS: 'ai_job_portal_notifications',
|
|
CALENDAR: 'ai_job_portal_calendar'
|
|
};
|
|
|
|
export async function fetchApplications(): Promise<JobApplication[]> {
|
|
try {
|
|
const res = await fetch('/api/local/data?key=' + STORAGE_KEYS.APPLICATIONS);
|
|
if (res.ok) {
|
|
const data = await res.json();
|
|
if (Array.isArray(data.items)) return data.items;
|
|
}
|
|
} catch (e) {
|
|
console.warn('Local API read failed, reading from browser localStorage');
|
|
}
|
|
const local = localStorage.getItem(STORAGE_KEYS.APPLICATIONS);
|
|
return local ? JSON.parse(local) : [];
|
|
}
|
|
|
|
export async function saveApplication(appData: Omit<JobApplication, 'id'> & { id?: string }): Promise<JobApplication> {
|
|
const id = appData.id || `app_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`;
|
|
const record: JobApplication = { ...appData, id };
|
|
|
|
const list = await fetchApplications();
|
|
const idx = list.findIndex(a => a.id === id);
|
|
if (idx >= 0) list[idx] = record;
|
|
else list.unshift(record);
|
|
|
|
localStorage.setItem(STORAGE_KEYS.APPLICATIONS, JSON.stringify(list));
|
|
|
|
try {
|
|
await fetch('/api/local/data', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ key: STORAGE_KEYS.APPLICATIONS, items: list })
|
|
});
|
|
} catch (e) {
|
|
console.warn('Failed to sync to local disk file');
|
|
}
|
|
|
|
return record;
|
|
}
|
|
|
|
export async function updateApplicationStatus(id: string, status: JobApplication['status'], note?: string): Promise<void> {
|
|
const list = await fetchApplications();
|
|
const target = list.find(a => a.id === id);
|
|
if (target) {
|
|
target.status = status;
|
|
if (note) target.notes = note;
|
|
if (!target.timeline) target.timeline = [];
|
|
target.timeline.unshift({
|
|
date: new Date().toLocaleDateString() + ' ' + new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
|
|
action: `Status updated to ${status}`
|
|
});
|
|
await saveApplication(target);
|
|
}
|
|
}
|
|
|
|
export async function deleteApplicationRecord(id: string): Promise<void> {
|
|
const list = await fetchApplications();
|
|
const updated = list.filter(a => a.id !== id);
|
|
localStorage.setItem(STORAGE_KEYS.APPLICATIONS, JSON.stringify(updated));
|
|
|
|
try {
|
|
await fetch('/api/local/data', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ key: STORAGE_KEYS.APPLICATIONS, items: updated })
|
|
});
|
|
} catch (e) {}
|
|
}
|
|
|
|
export async function fetchUserProfile(): Promise<UserProfile | null> {
|
|
try {
|
|
const res = await fetch('/api/local/data?key=' + STORAGE_KEYS.USER_PROFILE);
|
|
if (res.ok) {
|
|
const data = await res.json();
|
|
if (data.profile) return data.profile;
|
|
}
|
|
} catch (e) {}
|
|
|
|
const local = localStorage.getItem(STORAGE_KEYS.USER_PROFILE);
|
|
return local ? JSON.parse(local) : null;
|
|
}
|
|
|
|
export async function saveUserProfile(profile: UserProfile): Promise<void> {
|
|
localStorage.setItem(STORAGE_KEYS.USER_PROFILE, JSON.stringify(profile));
|
|
|
|
try {
|
|
await fetch('/api/local/data', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ key: STORAGE_KEYS.USER_PROFILE, profile })
|
|
});
|
|
} catch (e) {}
|
|
}
|
|
|
|
export async function fetchNotifications(): Promise<NotificationLog[]> {
|
|
const local = localStorage.getItem(STORAGE_KEYS.NOTIFICATIONS);
|
|
return local ? JSON.parse(local) : [];
|
|
}
|
|
|
|
export async function saveNotificationLog(notifData: Omit<NotificationLog, 'id'>): Promise<NotificationLog> {
|
|
const id = `notif_${Date.now()}_${Math.random().toString(36).substring(2, 6)}`;
|
|
const record: NotificationLog = { ...notifData, id };
|
|
const list = await fetchNotifications();
|
|
list.unshift(record);
|
|
localStorage.setItem(STORAGE_KEYS.NOTIFICATIONS, JSON.stringify(list));
|
|
return record;
|
|
}
|
|
|
|
export async function fetchCalendarEvents(): Promise<CalendarInterviewEvent[]> {
|
|
const local = localStorage.getItem(STORAGE_KEYS.CALENDAR);
|
|
return local ? JSON.parse(local) : [];
|
|
}
|
|
|
|
export async function saveCalendarEvent(eventData: Omit<CalendarInterviewEvent, 'id'> & { id?: string }): Promise<CalendarInterviewEvent> {
|
|
const id = eventData.id || `evt_${Date.now()}_${Math.random().toString(36).substring(2, 6)}`;
|
|
const record: CalendarInterviewEvent = { ...eventData, id };
|
|
const list = await fetchCalendarEvents();
|
|
list.push(record);
|
|
localStorage.setItem(STORAGE_KEYS.CALENDAR, JSON.stringify(list));
|
|
return record;
|
|
}
|