feat: add Home page with user dashboard and habit tracking features
- Implemented Home component with user authentication and loading states. - Created Welcome component for unauthenticated users with a sign-in option. - Developed Dashboard component to display user's habits and progress. - Added functionality for habit management, including adding, updating, and deleting habits. - Integrated HabitChart and HabitHistory components for visual representation of habits. - Introduced sharing functionality for progress via Discord integration. feat: establish Discord sharing configuration and routes - Added DiscordSharingConfig type and readDiscordSharingConfig function for environment variable management. - Created sharing contracts for input validation and data structure. - Implemented sharing routes for previewing and sending progress images to Discord. - Added tests for sharing routes to ensure authentication and proper error handling.
This commit is contained in:
@@ -6,6 +6,19 @@ import index from "../src/index.html";
|
||||
const f = fixture();
|
||||
const origin = "http://127.0.0.1:3107";
|
||||
const previewCookie = "minabot_dashboard_preview_session";
|
||||
const sharingPreview = process.env.SHARE_PREVIEW === "1";
|
||||
let sharedImage: Blob | null = null;
|
||||
if (sharingPreview) {
|
||||
f.setTime("2026-08-01T12:00:00Z");
|
||||
const reading = await f.json("/habits", "POST", { name: "A few pages, every day", method: "count", target: 10, unit: "pages", color: "#90647e" }, 201);
|
||||
const walking = await f.json("/habits", "POST", { name: "An afternoon walk", method: "manual", schedule: { type: "weekdays", days: [1, 3, 5] }, color: "#397f76" }, 201);
|
||||
for (let i = 0; i < 35; i++) {
|
||||
const date = new Date(Date.UTC(2026, 7, 1 + i)).toISOString().slice(0, 10);
|
||||
f.setTime(`${date}T12:00:00Z`);
|
||||
if (i % 4 !== 0) await f.json(`/habits/${reading.id}/days/${date}/progress`, "PUT", { count: i % 3 === 0 ? 5 : 10 });
|
||||
if ([1, 3, 5].includes(new Date(`${date}T12:00:00Z`).getUTCDay()) && i % 4 !== 0) await f.json(`/habits/${walking.id}/days/${date}/progress`, "PUT", { done: true });
|
||||
}
|
||||
}
|
||||
const app = createApi(
|
||||
f.db,
|
||||
{
|
||||
@@ -16,11 +29,20 @@ const app = createApi(
|
||||
},
|
||||
undefined,
|
||||
() => Date.parse("2026-09-04T12:00:00Z"),
|
||||
sharingPreview ? async (_url, init) => {
|
||||
if (init?.method === "POST") {
|
||||
sharedImage = (init.body as FormData).get("files[0]") as Blob;
|
||||
return Response.json({ id: "423456789012345678" });
|
||||
}
|
||||
return Response.json({ type: 0, id: "223456789012345678", guild_id: "323456789012345678", name: "preview-only" });
|
||||
} : undefined,
|
||||
sharingPreview ? { token: "preview-bot-token", channelId: "223456789012345678" } : undefined,
|
||||
);
|
||||
const server = Bun.serve({
|
||||
hostname: "127.0.0.1",
|
||||
port: 3107,
|
||||
routes: {
|
||||
"/__preview/shared-image": () => sharingPreview && sharedImage ? new Response(sharedImage) : new Response(null, { status: 404 }),
|
||||
"/__preview/login": () =>
|
||||
new Response(null, {
|
||||
status: 302,
|
||||
|
||||
Reference in New Issue
Block a user