Action

Type

Resolved On

Create Monthly Goal in FE feature 2026-02-03

Create Monthly Goal in FE

Overview

Implemented the ability to create monthly goals directly from the frontend UI when logged in. Users can now set their monthly goal from the Header component when the goal is “Undefined”.

Problem

Previously, monthly goals could only be created through direct database access or backend operations. Users had no way to set their monthly goal from the frontend interface, even when authenticated.

Solution

Implementation Summary

Added goal creation functionality to the Header components for both benben and hygge layouts. When a user is authenticated and viewing the current month’s Goal page with an “Undefined” goal, an editable input field appears allowing them to set the goal.

New Functions Added

FileFunctionDescription
src/lib/new.tsmonthlyGoal(owner, year, month, goalText)Creates a new monthly goal with due date set to last day of the month

API Endpoint Created

EndpointMethodDescription
/api/new/goalPOSTAccepts owner, year, month, and goal text to create a monthly goal

Files Updated

FileChanges
src/lib/new.tsAdded monthlyGoal() function for inserting new monthly goals
src/pages/api/new/goal.tsNew API endpoint for creating monthly goals
src/components/navigation/benben/Header.astroAdded authentication check, goal input form with Save button, and client-side JS for form submission
src/components/navigation/hygge/Header.astroAdded authentication check, goal input form with Save button, and client-side JS for form submission

Key Implementation Details

Authentication Check:

const accessToken = Astro.cookies.get("sb-access-token");
const refreshToken = Astro.cookies.get("sb-refresh-token");
let auth = false;
if (accessToken && refreshToken) {
  // Validate session with Supabase
  auth = true;
}

Edit Condition (only for current month’s undefined goals):

const isCurrentMonth = index === 0; // No date prefix in URL
const isGoalPage = loc === "" && heading !== undefined;
const canEdit = auth && isGoalPage && isCurrentMonth && heading === "Undefined";

Goal Insert Logic:

const dueDate = format(
  new Date(year, month, 0), // Day 0 of next month = last day of current month
  "yyyy-MM-dd",
);

const { error } = await supabase
  .from("Goals")
  .insert({ goal: goalText, due: dueDate, owner: owner, monthly: true });

User Flow

  1. User logs in via Supabase authentication
  2. Navigates to /benben or /hygge (current month’s Goal page)
  3. If goal is “Undefined”, sees an editable input field instead of static text
  4. Types the goal text - “Save” button appears
  5. Clicks Save or presses Enter
  6. Goal is created in database via API
  7. Page reloads showing the new goal

Benefits

  • Self-Service Goal Setting: Users can set monthly goals without backend access
  • Authentication Required: Only logged-in users can create goals
  • Current Month Only: Prevents accidental modification of historical data
  • Intuitive UX: Input field appears inline where the goal displays
  • Immediate Feedback: Save button shows when changes are made, page reloads on success

Technical Notes

  • Goal editing only appears when heading === "Undefined" - this is an insert-only operation
  • The due date is automatically set to the last day of the current month
  • Year and month are derived from the current system date, not passed as props
  • Uses the same authentication pattern as other editable components (Sidebar, NewIdea, etc.)