Skip to content

implemented Habit dashboard and check-in flow (Closes #18)#29

Open
vedhapprakashni wants to merge 6 commits intoZenYukti:mainfrom
vedhapprakashni:habit
Open

implemented Habit dashboard and check-in flow (Closes #18)#29
vedhapprakashni wants to merge 6 commits intoZenYukti:mainfrom
vedhapprakashni:habit

Conversation

@vedhapprakashni
Copy link

@vedhapprakashni vedhapprakashni commented Feb 6, 2026

Added a comprehensive habit tracking system to OpenMindWell, allowing users to create, track, and manage personal habits with streak tracking and progress visualization.

Type of Change

  • ✨ New feature (non-breaking change which adds functionality)

How Has This Been Tested?

Manual testing performed for all habit operations including create, edit, delete, and check in. Verified streak calculation logic works correctly for consecutive days. Confirmed responsive design on various screen sizes.

Preview

openmindwell.mp4

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Additional Information

The .env.example files contain placeholder values and should be copied to .env with actual credentials for local development. All sensitive data has been removed from version control.

Features included:
Users can create custom habits with configurable frequency options such as daily and weekly.
Visual streak tracking shows current streak and longest streak achieved.
Check in functionality allows users to mark habits as completed each day.
Edit and delete capabilities for habit management.
Responsive dashboard layout with animated components.

Technical implementation:
Frontend components built with React and TypeScript.
Backend API routes implemented in Express.
Supabase integration for data persistence.

@github-actions github-actions bot added frontend Client-side features and views ui/ux labels Feb 6, 2026
@ayushHardeniya ayushHardeniya linked an issue Feb 6, 2026 that may be closed by this pull request
@ayushHardeniya ayushHardeniya added the apertre3.0 Apertre 3.0 open source program label Feb 6, 2026
@Blazzzeee Blazzzeee requested a review from Copilot March 1, 2026 19:07
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements a new Habits dashboard experience in the OpenMindWell frontend, adding UI flows for creating, editing, checking-in, and deleting habits (per #18), along with supporting API client calls and styling.

Changes:

  • Adds a Habits tab UI in Dashboard.tsx with CRUD + check-in modals.
  • Extends the frontend API client with additional habits endpoints (including a “today logs” fetch).
  • Introduces global CSS for modals/streak badges/confetti and updates .env.example placeholder values.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
frontend/src/pages/Dashboard.tsx Adds Habits tab state management and integrates the new habit modals + cards.
frontend/src/lib/api.ts Adds habitsApi.getTodayLogs() and wires habits API calls used by the dashboard.
frontend/src/index.css Adds modal, habit card, streak badge, confetti, and bounce animation styles.
frontend/src/components/HabitCard.tsx New habit card component with edit/delete actions and check-in CTA.
frontend/src/components/CreateHabitModal.tsx New modal for creating a habit.
frontend/src/components/EditHabitModal.tsx New modal for editing a habit.
frontend/src/components/CheckInModal.tsx New modal for habit check-in with milestone/confetti UX.
frontend/src/components/DeleteConfirmModal.tsx New confirmation modal for habit deletion.
frontend/.env.example Replaces Supabase placeholder values with clearer placeholders.
backend/.env.example Replaces Supabase/HuggingFace placeholder values with clearer placeholders.
.env.example Replaces Supabase placeholder values with clearer placeholders.
Comments suppressed due to low confidence (11)

frontend/src/pages/Dashboard.tsx:236

  • PR description/checklist claims automated tests were added/passing, but this PR doesn’t introduce tests and the repo scripts don’t include a test runner. Either update the PR description to reflect manual-only testing or add automated coverage for the new habit flow.
function HabitsTab() {
  const [habits, setHabits] = useState<any[]>([]);
  const [todayLogs, setTodayLogs] = useState<Record<string, any>>({});
  const [loading, setLoading] = useState(true);

frontend/src/components/HabitCard.tsx:39

  • Icon-only edit button relies on emoji + title, which is not a reliable accessible name for screen readers. Add aria-label (and/or visually hidden text) so the control is accessible.
                    <button
                        onClick={onEdit}
                        className="p-2 text-gray-400 hover:text-primary-600 hover:bg-primary-50 rounded-lg transition-colors"
                        title="Edit habit"
                    >

frontend/src/components/HabitCard.tsx:47

  • Icon-only delete button relies on emoji + title, which is not a reliable accessible name for screen readers. Add aria-label (and/or visually hidden text) so the control is accessible.
                        onClick={onDelete}
                        className="p-2 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors"
                        title="Delete habit"
                    >
                        🗑️

frontend/src/pages/Dashboard.tsx:266

  • setHabits([newHabit, ...habits]) uses the captured habits value. If multiple creates happen before state flushes, this can drop items. Prefer a functional state update (setHabits(prev => [newHabit, ...prev])) to avoid stale-closure bugs.
    const newHabit = await habitsApi.create(habit);
    setHabits([newHabit, ...habits]);
  }

frontend/src/pages/Dashboard.tsx:280

  • These state updates use captured todayLogs/habits values. Rapid successive check-ins can lose updates due to stale closures. Prefer functional updates (e.g., setTodayLogs(prev => ...), setHabits(prev => prev.map(...))).
    setTodayLogs({ ...todayLogs, [habitId]: result });
    // Update streak in habits list
    setHabits(habits.map(h =>
      h.id === habitId ? { ...h, current_streak: result.new_streak } : h
    ));

frontend/src/index.css:166

  • This file defines a global .animate-bounce class, but Tailwind already provides an animate-bounce utility. Overriding it in global CSS can unexpectedly change animation behavior elsewhere. Consider renaming this custom class (or configuring the animation via tailwind.config instead) to avoid collisions.
/* Bounce animation */
.animate-bounce {
  animation: bounce 1s infinite;
}

frontend/src/components/CreateHabitModal.tsx:57

  • The close (×) button lacks an accessible name. Add aria-label="Close" so keyboard/screen-reader users can identify it (similar to ChatRoom).
                    <button
                        onClick={onClose}
                        className="text-gray-400 hover:text-gray-600 text-2xl leading-none"
                    >
                        ×

frontend/src/components/EditHabitModal.tsx:68

  • The close (×) button lacks an accessible name. Add aria-label="Close" so keyboard/screen-reader users can identify it.
                    <button
                        onClick={onClose}
                        className="text-gray-400 hover:text-gray-600 text-2xl leading-none"
                    >
                        ×

frontend/src/components/CheckInModal.tsx:123

  • The close (×) button lacks an accessible name. Add aria-label="Close" so keyboard/screen-reader users can identify it.
                            <button
                                onClick={onClose}
                                className="text-gray-400 hover:text-gray-600 text-2xl leading-none"
                            >
                                ×

frontend/src/components/CheckInModal.tsx:60

  • The setTimeout delay is based on showConfetti, but showConfetti is set via state earlier in the same function. Because state updates are async, this closure will usually see the previous value (typically false), so milestone check-ins won’t get the intended longer delay. Compute the delay from a local hitMilestone boolean instead.
            setTimeout(() => {
                onClose();
            }, showConfetti ? 3000 : 1500);
        } catch (err) {

frontend/src/components/CheckInModal.tsx:60

  • The auto-close setTimeout isn’t cleared if the user closes the modal manually (or if it unmounts). This can call onClose() after the modal is already closed. Store the timeout id and clear it in an effect cleanup / before scheduling a new timeout.
            // Auto-close after delay
            setTimeout(() => {
                onClose();
            }, showConfetti ? 3000 : 1500);
        } catch (err) {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

getAll: () => apiFetch('/api/habits'),


getTodayLogs: () => apiFetch('/api/habits/today'),
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

habitsApi.getTodayLogs() calls GET /api/habits/today, but the backend habits router currently exposes only /, /:id/log, /:id/logs, /:id (PUT/DELETE). This will 404 at runtime unless a matching backend route is added or the frontend is changed to derive “today” completion status from existing endpoints.

Suggested change
getTodayLogs: () => apiFetch('/api/habits/today'),
getTodayLogs: () => apiFetch('/api/habits'),

Copilot uses AI. Check for mistakes.
Comment on lines +277 to +280
// Update streak in habits list
setHabits(habits.map(h =>
h.id === habitId ? { ...h, current_streak: result.new_streak } : h
));
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

result.new_streak is assumed to exist, but the backend POST /api/habits/:id/log currently returns the inserted habit_logs row (no new_streak). As written, this will set current_streak to undefined and break streak display. Align the frontend with the API response or return streak info from the backend.

Suggested change
// Update streak in habits list
setHabits(habits.map(h =>
h.id === habitId ? { ...h, current_streak: result.new_streak } : h
));
// The log endpoint currently returns only the habit_log row and does not
// include updated streak information. To avoid overwriting the existing
// streak with undefined, we leave current_streak unchanged here. Any
// subsequent reload of habits will refresh streak data from the backend.

Copilot uses AI. Check for mistakes.
Comment on lines +250 to +255
const [habitsData, logsData] = await Promise.all([
habitsApi.getAll(),
habitsApi.getTodayLogs(),
]);
setHabits(habitsData);
setTodayLogs(logsData);
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loadHabits() calls habitsApi.getTodayLogs(), but there is no /api/habits/today route in the current backend habits router. This will 404 and prevent habits from loading unless the backend adds the endpoint or the frontend derives “checked in today” from existing log data.

Suggested change
const [habitsData, logsData] = await Promise.all([
habitsApi.getAll(),
habitsApi.getTodayLogs(),
]);
setHabits(habitsData);
setTodayLogs(logsData);
const habitsData = await habitsApi.getAll();
setHabits(habitsData);
// Fallback: no dedicated "today logs" endpoint available, so initialize as empty.
setTodayLogs({});

Copilot uses AI. Check for mistakes.
@Blazzzeee
Copy link
Collaborator

@vedhapprakashni please update your code on these changes , if the changes arent reflected till next week , we will need to close the PR

@vedhapprakashni
Copy link
Author

@Blazzzeee pls check and add difficulty label

@ayushHardeniya ayushHardeniya added the hard high-impact changes with significant technical depth label Mar 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

apertre3.0 Apertre 3.0 open source program frontend Client-side features and views hard high-impact changes with significant technical depth ui/ux

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: implement Habit dashboard and check-in flow

4 participants