Phase 4: Add @bytelyst/feedback-client, broadcast-client, survey-client, offline-queue wrappers. Revamp settings page with profile, password change, feedback form. Add BroadcastBanner and SurveyBanner to app layout. Wire offline queue flush on boot. Phase 5: Fix .env.example branding (NoteLett), update docker-compose with all env vars, enable GitHub Actions CI workflow with lint steps. Made-with: Cursor
37 lines
1.0 KiB
TypeScript
37 lines
1.0 KiB
TypeScript
"use client";
|
|
|
|
import { createOfflineQueue, type OfflineQueue } from "@bytelyst/offline-queue";
|
|
import { PRODUCT_ID } from "@/lib/product-config";
|
|
import { createNotesApiClient } from "@/lib/api-helpers";
|
|
|
|
const ACTION_METHOD: Record<string, string> = {
|
|
create: "POST",
|
|
update: "PATCH",
|
|
delete: "DELETE",
|
|
};
|
|
|
|
let _queue: OfflineQueue | null = null;
|
|
export function getOfflineQueue(): OfflineQueue {
|
|
if (!_queue) {
|
|
_queue = createOfflineQueue({
|
|
storageKey: `${PRODUCT_ID}_offline_queue`,
|
|
storage: typeof window !== "undefined" ? localStorage : { getItem: () => null, setItem: () => {} },
|
|
});
|
|
}
|
|
return _queue;
|
|
}
|
|
|
|
export async function flushOfflineQueue(): Promise<{ flushed: number; failed: number }> {
|
|
const queue = getOfflineQueue();
|
|
const api = createNotesApiClient();
|
|
|
|
return queue.flush(async (action, path, payload) => {
|
|
const method = ACTION_METHOD[action] ?? "POST";
|
|
await api.fetch(path, {
|
|
method,
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify(payload),
|
|
});
|
|
});
|
|
}
|