From 74c73a9e8f3b10be1fbdb6dbabf44d0edf95c034 Mon Sep 17 00:00:00 2001 From: mohamad <mohamad> Date: Sun, 1 Jun 2025 14:10:59 +0200 Subject: [PATCH] refactor: Update GroupsPage to use standard HTML for now --- fe/src/pages/GroupsPage.vue | 148 ++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/fe/src/pages/GroupsPage.vue b/fe/src/pages/GroupsPage.vue index ea0b40b..b0fb71b 100644 --- a/fe/src/pages/GroupsPage.vue +++ b/fe/src/pages/GroupsPage.vue @@ -2,33 +2,41 @@ <main class="container page-padding"> <!-- <h1 class="mb-3">Your Groups</h1> --> - <VAlert v-if="fetchError" type="error" :message="fetchError" class="mb-3" :closable="false"> - <template #actions> - <VButton variant="danger" size="sm" @click="fetchGroups">Retry</VButton> - </template> - </VAlert> + <div v-if="fetchError" class="alert alert-error mb-3" role="alert"> + <div class="alert-content"> + <svg class="icon" aria-hidden="true"> + <use xlink:href="#icon-alert-triangle" /> + </svg> + {{ fetchError }} + </div> + <button type="button" class="btn btn-sm btn-danger" @click="fetchGroups">Retry</button> + </div> - <VCard v-else-if="groups.length === 0" - variant="empty-state" - empty-icon="clipboard" - empty-title="No Groups Yet!" - empty-message="You are not a member of any groups yet. Create one or join using an invite code." - > - <template #empty-actions> - <VButton variant="primary" class="mt-2" @click="openCreateGroupDialog" icon-left="plus"> - Create New Group - </VButton> - </template> - </VCard> + <div v-else-if="groups.length === 0" class="card empty-state-card"> + <svg class="icon icon-lg" aria-hidden="true"> + <use xlink:href="#icon-clipboard" /> + </svg> + <h3>No Groups Yet!</h3> + <p>You are not a member of any groups yet. Create one or join using an invite code.</p> + <button class="btn btn-primary mt-2" @click="openCreateGroupDialog"> + <svg class="icon" aria-hidden="true"> + <use xlink:href="#icon-plus" /> + </svg> + Create New Group + </button> + </div> <div v-else class="mb-3"> <div class="neo-groups-grid"> <div v-for="group in groups" :key="group.id" class="neo-group-card" @click="selectGroup(group)"> <h1 class="neo-group-header">{{ group.name }}</h1> <div class="neo-group-actions"> - <VButton size="sm" variant="secondary" @click.stop="openCreateListDialog(group)" icon-left="plus"> + <button class="btn btn-sm btn-secondary" @click.stop="openCreateListDialog(group)"> + <svg class="icon" aria-hidden="true"> + <use xlink:href="#icon-plus" /> + </svg> List - </VButton> + </button> </div> </div> <div class="neo-create-group-card" @click="openCreateGroupDialog"> @@ -48,48 +56,52 @@ </summary> <div class="card-body"> <form @submit.prevent="handleJoinGroup" class="flex items-center" style="gap: 0.5rem;"> - <VFormField class="flex-grow" :error-message="joinGroupFormError" label="Enter Invite Code" :label-sr-only="true"> - <VInput - type="text" - id="joinInviteCodeInput" - v-model="inviteCodeToJoin" - placeholder="Enter Invite Code" - required - ref="joinInviteCodeInputRef" - /> - </VFormField> - <VButton type="submit" variant="secondary" :disabled="joiningGroup"> - <VSpinner v-if="joiningGroup" size="sm" /> + <div class="form-group flex-grow" style="margin-bottom: 0;"> + <label for="joinInviteCodeInput" class="sr-only">Enter Invite Code</label> + <input type="text" id="joinInviteCodeInput" v-model="inviteCodeToJoin" class="form-input" + placeholder="Enter Invite Code" required ref="joinInviteCodeInputRef" /> + </div> + <button type="submit" class="btn btn-secondary" :disabled="joiningGroup"> + <span v-if="joiningGroup" class="spinner-dots-sm" role="status"><span /><span /><span /></span> Join - </VButton> + </button> </form> - <!-- The error message is now handled by VFormField --> + <p v-if="joinGroupFormError" class="form-error-text mt-1">{{ joinGroupFormError }}</p> </div> </details> </div> <!-- Create Group Dialog --> - <VModal v-model="showCreateGroupDialog" title="Create New Group" @update:modelValue="val => !val && closeCreateGroupDialog()"> - <form @submit.prevent="handleCreateGroup"> - <VFormField label="Group Name" :error-message="createGroupFormError"> - <VInput - type="text" - v-model="newGroupName" - placeholder="Enter group name" - required - id="newGroupNameInput" - ref="newGroupNameInputRef" - /> - </VFormField> - <template #footer> - <VButton variant="neutral" @click="closeCreateGroupDialog" type="button">Cancel</VButton> - <VButton type="submit" variant="primary" :disabled="creatingGroup"> - <VSpinner v-if="creatingGroup" size="sm" /> - Create - </VButton> - </template> - </form> - </VModal> + <div v-if="showCreateGroupDialog" class="modal-backdrop open" @click.self="closeCreateGroupDialog"> + <div class="modal-container" ref="createGroupModalRef" role="dialog" aria-modal="true" + aria-labelledby="createGroupTitle"> + <div class="modal-header"> + <h3 id="createGroupTitle">Create New Group</h3> + <button class="close-button" @click="closeCreateGroupDialog" aria-label="Close"> + <svg class="icon" aria-hidden="true"> + <use xlink:href="#icon-close" /> + </svg> + </button> + </div> + <form @submit.prevent="handleCreateGroup"> + <div class="modal-body"> + <div class="form-group"> + <label for="newGroupNameInput" class="form-label">Group Name</label> + <input type="text" id="newGroupNameInput" v-model="newGroupName" class="form-input" required + ref="newGroupNameInputRef" /> + <p v-if="createGroupFormError" class="form-error-text">{{ createGroupFormError }}</p> + </div> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-neutral" @click="closeCreateGroupDialog">Cancel</button> + <button type="submit" class="btn btn-primary ml-2" :disabled="creatingGroup"> + <span v-if="creatingGroup" class="spinner-dots-sm" role="status"><span /><span /><span /></span> + Create + </button> + </div> + </form> + </div> + </div> <!-- Create List Modal --> <CreateListModal v-model="showCreateListModal" :groups="availableGroupsForModal" @created="onListCreated" /> @@ -101,16 +113,9 @@ import { ref, onMounted, nextTick } from 'vue'; import { useRouter } from 'vue-router'; import { apiClient, API_ENDPOINTS } from '@/config/api'; import { useStorage } from '@vueuse/core'; -// import { onClickOutside } from '@vueuse/core'; // No longer needed for VModal +import { onClickOutside } from '@vueuse/core'; import { useNotificationStore } from '@/stores/notifications'; import CreateListModal from '@/components/CreateListModal.vue'; -import VModal from '@/components/valerie/VModal.vue'; -import VFormField from '@/components/valerie/VFormField.vue'; -import VInput from '@/components/valerie/VInput.vue'; -import VButton from '@/components/valerie/VButton.vue'; -import VSpinner from '@/components/valerie/VSpinner.vue'; -import VAlert from '@/components/valerie/VAlert.vue'; -import VCard from '@/components/valerie/VCard.vue'; interface Group { id: number; @@ -130,13 +135,13 @@ const fetchError = ref<string | null>(null); const showCreateGroupDialog = ref(false); const newGroupName = ref(''); const creatingGroup = ref(false); -const newGroupNameInputRef = ref<InstanceType<typeof VInput> | null>(null); // Changed type to VInput instance -// const createGroupModalRef = ref<HTMLElement | null>(null); // No longer needed +const newGroupNameInputRef = ref<HTMLInputElement | null>(null); +const createGroupModalRef = ref<HTMLElement | null>(null); const createGroupFormError = ref<string | null>(null); const inviteCodeToJoin = ref(''); const joiningGroup = ref(false); -const joinInviteCodeInputRef = ref<InstanceType<typeof VInput> | null>(null); // Changed type to VInput instance +const joinInviteCodeInputRef = ref<HTMLInputElement | null>(null); const joinGroupFormError = ref<string | null>(null); const showCreateListModal = ref(false); @@ -178,12 +183,7 @@ const openCreateGroupDialog = () => { createGroupFormError.value = null; showCreateGroupDialog.value = true; nextTick(() => { - // Attempt to focus VInput. This assumes VInput exposes a focus method - // or internally focuses its input element on a `focus()` call. - // If VInput's input element needs to be accessed directly, it might be: - // newGroupNameInputRef.value?.$el.querySelector('input')?.focus(); or similar, - // but ideally VInput itself handles this. - newGroupNameInputRef.value?.focus?.(); + newGroupNameInputRef.value?.focus(); }); }; @@ -191,12 +191,12 @@ const closeCreateGroupDialog = () => { showCreateGroupDialog.value = false; }; -// onClickOutside(createGroupModalRef, closeCreateGroupDialog); // Replaced by VModal's own handling +onClickOutside(createGroupModalRef, closeCreateGroupDialog); const handleCreateGroup = async () => { if (!newGroupName.value.trim()) { createGroupFormError.value = 'Group name is required'; - newGroupNameInputRef.value?.focus?.(); // Use VInput's focus method if available + newGroupNameInputRef.value?.focus(); return; } createGroupFormError.value = null; @@ -229,7 +229,7 @@ const handleCreateGroup = async () => { const handleJoinGroup = async () => { if (!inviteCodeToJoin.value.trim()) { joinGroupFormError.value = 'Invite code is required'; - joinInviteCodeInputRef.value?.focus?.(); // Use VInput's focus method if available + joinInviteCodeInputRef.value?.focus(); return; } joinGroupFormError.value = null;