-
{{ $t('accountPage.notificationsSection.groupActivitiesLabel') }}
-
{{ $t('accountPage.notificationsSection.groupActivitiesDescription') }}
+
+
+
+ {{
+ $t('accountPage.notificationsSection.groupActivitiesLabel')
+ }}
+ {{
+ $t('accountPage.notificationsSection.groupActivitiesDescription')
+ }}
-
-
-
-
+
+
+
@@ -97,16 +126,7 @@ import { useI18n } from 'vue-i18n';
import { useAuthStore } from '@/stores/auth';
import { apiClient, API_ENDPOINTS } from '@/services/api'; // Assuming path
import { useNotificationStore } from '@/stores/notifications';
-import VHeading from '@/components/valerie/VHeading.vue';
-import VSpinner from '@/components/valerie/VSpinner.vue';
-import VAlert from '@/components/valerie/VAlert.vue';
-import VCard from '@/components/valerie/VCard.vue';
-import VFormField from '@/components/valerie/VFormField.vue';
-import VInput from '@/components/valerie/VInput.vue';
-import VButton from '@/components/valerie/VButton.vue';
-import VToggleSwitch from '@/components/valerie/VToggleSwitch.vue';
-import VList from '@/components/valerie/VList.vue';
-import VListItem from '@/components/valerie/VListItem.vue';
+import { Heading, Spinner, Alert, Card, Input, Button, Switch } from '@/components/ui';
const { t } = useI18n();
diff --git a/fe/src/pages/ChoresPage.vue b/fe/src/pages/ChoresPage.vue
index c0f7b35..4793f35 100644
--- a/fe/src/pages/ChoresPage.vue
+++ b/fe/src/pages/ChoresPage.vue
@@ -4,15 +4,21 @@ import { useI18n } from 'vue-i18n'
import { format, startOfDay, isEqual, isToday as isTodayDate, formatDistanceToNow, parseISO } from 'date-fns'
import { choreService } from '../services/choreService'
import { useNotificationStore } from '../stores/notifications'
-import type { Chore, ChoreCreate, ChoreUpdate, ChoreFrequency, ChoreAssignmentUpdate, ChoreAssignment, ChoreHistory, ChoreWithCompletion } from '../types/chore'
+import type { Chore, ChoreCreate, ChoreUpdate, ChoreFrequency, ChoreAssignment, ChoreHistory, ChoreWithCompletion } from '../types/chore'
import { groupService } from '../services/groupService'
import { useStorage } from '@vueuse/core'
import ChoreItem from '@/components/ChoreItem.vue';
-import { useTimeEntryStore, type TimeEntry } from '../stores/timeEntryStore';
-import { storeToRefs } from 'pinia';
+import { useChoreStore } from '@/stores/choreStore';
import { useAuthStore } from '@/stores/auth';
import type { UserPublic } from '@/types/user';
import BaseIcon from '@/components/BaseIcon.vue';
+import ChoreDetailSheet from '@/components/ChoreDetailSheet.vue';
+import Dialog from '@/components/ui/Dialog.vue';
+import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from '@headlessui/vue';
+import { TransitionExpand } from '@/components/ui';
+import { Button } from '@/components/ui';
+import QuickChoreAdd from '@/components/QuickChoreAdd.vue';
+import { storeToRefs } from 'pinia'
const { t } = useI18n()
@@ -75,15 +81,10 @@ const isLoading = ref(true)
const authStore = useAuthStore();
const { isGuest, user } = storeToRefs(authStore);
-const timeEntryStore = useTimeEntryStore();
-const { timeEntries, loading: timeEntryLoading, error: timeEntryError } = storeToRefs(timeEntryStore);
+const choreStore = useChoreStore();
const activeTimer = computed(() => {
- for (const assignmentId in timeEntries.value) {
- const entry = timeEntries.value[assignmentId].find(te => !te.end_time);
- if (entry) return entry;
- }
- return null;
+ return choreStore.activeTimerEntry;
});
const loadChores = async () => {
@@ -143,7 +144,7 @@ const loadGroups = async () => {
const loadTimeEntries = async () => {
chores.value.forEach(chore => {
if (chore.current_assignment_id) {
- timeEntryStore.fetchTimeEntriesForAssignment(chore.current_assignment_id);
+ choreStore.fetchTimeEntries(chore.current_assignment_id);
}
});
};
@@ -410,51 +411,23 @@ const deleteChore = async () => {
}
const toggleCompletion = async (chore: ChoreWithCompletion) => {
- if (chore.current_assignment_id === null) {
- // If no assignment exists, create one
- try {
- const assignment = await choreService.createAssignment({
- chore_id: chore.id,
- assigned_to_user_id: chore.created_by_id,
- due_date: chore.next_due_date
- });
- chore.current_assignment_id = assignment.id;
- } catch (error) {
- console.error(t('choresPage.consoleErrors.createAssignmentFailed'), error);
- notificationStore.addNotification({
- message: t('choresPage.notifications.createAssignmentFailed', 'Failed to create assignment for chore.'),
- type: 'error'
- });
- return;
- }
- }
-
- const originalCompleted = chore.is_completed;
- chore.updating = true;
- const newCompletedStatus = !chore.is_completed;
- chore.is_completed = newCompletedStatus;
-
+ const assignment = chore.current_assignment_id
+ ? chore.assignments?.find(a => a.id === chore.current_assignment_id) || null
+ : null
try {
- if (newCompletedStatus) {
- await choreService.completeAssignment(chore.current_assignment_id);
- } else {
- const assignmentUpdate: ChoreAssignmentUpdate = { is_complete: false };
- await choreService.updateAssignment(chore.current_assignment_id, assignmentUpdate);
- }
-
+ await choreStore.toggleCompletion(chore, assignment as any)
+ await loadChores()
notificationStore.addNotification({
- message: newCompletedStatus ? t('choresPage.notifications.completed', 'Chore marked as complete!') : t('choresPage.notifications.uncompleted', 'Chore marked as incomplete.'),
- type: 'success'
- });
- await loadChores();
- } catch (error) {
- console.error(t('choresPage.consoleErrors.updateCompletionStatusFailed'), error);
- notificationStore.addNotification({ message: t('choresPage.notifications.updateFailed', 'Failed to update chore status.'), type: 'error' });
- chore.is_completed = originalCompleted;
- } finally {
- chore.updating = false;
+ message: t('choresPage.notifications.updateSuccess', 'Chore status updated.'),
+ type: 'success',
+ })
+ } catch (e) {
+ notificationStore.addNotification({
+ message: t('choresPage.notifications.updateFailed', 'Failed to update chore status.'),
+ type: 'error',
+ })
}
-};
+}
const openChoreDetailModal = async (chore: ChoreWithCompletion) => {
selectedChore.value = chore;
@@ -545,15 +518,13 @@ const getDueDateStatus = (chore: ChoreWithCompletion) => {
};
const startTimer = async (chore: ChoreWithCompletion) => {
- if (chore.current_assignment_id) {
- await timeEntryStore.startTimeEntry(chore.current_assignment_id);
- }
+ if (chore.is_completed || !chore.current_assignment_id) return;
+ await choreStore.startTimer(chore.current_assignment_id);
};
const stopTimer = async (chore: ChoreWithCompletion, timeEntryId: number) => {
- if (chore.current_assignment_id) {
- await timeEntryStore.stopTimeEntry(chore.current_assignment_id, timeEntryId);
- }
+ if (!chore.current_assignment_id) return;
+ await choreStore.stopTimer(chore.current_assignment_id, timeEntryId);
};
const handleAssignChore = async (userId: number) => {
@@ -598,7 +569,7 @@ const getAssignmentIdForUser = (userId: number): number | null => {
-
+
You are using a guest account.
@@ -606,13 +577,20 @@ const getAssignmentIdForUser = (userId: number): number | null => {
to save your data permanently.
-
- {{ t('choresPage.title') }}
-
+
+
+ {{ t('choresPage.title') }}
+
+
+
+
+
+
@@ -635,7 +613,7 @@ const getAssignmentIdForUser = (userId: number): number | null => {
@@ -644,758 +622,253 @@ const getAssignmentIdForUser = (userId: number): number | null => {
-
-
-
-
-