refactor: Update GroupsPage to use standard HTML for now

This commit is contained in:
mohamad 2025-06-01 14:10:59 +02:00
parent 679169e4fb
commit 74c73a9e8f

View File

@ -2,33 +2,41 @@
<main class="container page-padding"> <main class="container page-padding">
<!-- <h1 class="mb-3">Your Groups</h1> --> <!-- <h1 class="mb-3">Your Groups</h1> -->
<VAlert v-if="fetchError" type="error" :message="fetchError" class="mb-3" :closable="false"> <div v-if="fetchError" class="alert alert-error mb-3" role="alert">
<template #actions> <div class="alert-content">
<VButton variant="danger" size="sm" @click="fetchGroups">Retry</VButton> <svg class="icon" aria-hidden="true">
</template> <use xlink:href="#icon-alert-triangle" />
</VAlert> </svg>
{{ fetchError }}
</div>
<button type="button" class="btn btn-sm btn-danger" @click="fetchGroups">Retry</button>
</div>
<VCard v-else-if="groups.length === 0" <div v-else-if="groups.length === 0" class="card empty-state-card">
variant="empty-state" <svg class="icon icon-lg" aria-hidden="true">
empty-icon="clipboard" <use xlink:href="#icon-clipboard" />
empty-title="No Groups Yet!" </svg>
empty-message="You are not a member of any groups yet. Create one or join using an invite code." <h3>No Groups Yet!</h3>
> <p>You are not a member of any groups yet. Create one or join using an invite code.</p>
<template #empty-actions> <button class="btn btn-primary mt-2" @click="openCreateGroupDialog">
<VButton variant="primary" class="mt-2" @click="openCreateGroupDialog" icon-left="plus"> <svg class="icon" aria-hidden="true">
Create New Group <use xlink:href="#icon-plus" />
</VButton> </svg>
</template> Create New Group
</VCard> </button>
</div>
<div v-else class="mb-3"> <div v-else class="mb-3">
<div class="neo-groups-grid"> <div class="neo-groups-grid">
<div v-for="group in groups" :key="group.id" class="neo-group-card" @click="selectGroup(group)"> <div v-for="group in groups" :key="group.id" class="neo-group-card" @click="selectGroup(group)">
<h1 class="neo-group-header">{{ group.name }}</h1> <h1 class="neo-group-header">{{ group.name }}</h1>
<div class="neo-group-actions"> <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 List
</VButton> </button>
</div> </div>
</div> </div>
<div class="neo-create-group-card" @click="openCreateGroupDialog"> <div class="neo-create-group-card" @click="openCreateGroupDialog">
@ -48,48 +56,52 @@
</summary> </summary>
<div class="card-body"> <div class="card-body">
<form @submit.prevent="handleJoinGroup" class="flex items-center" style="gap: 0.5rem;"> <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"> <div class="form-group flex-grow" style="margin-bottom: 0;">
<VInput <label for="joinInviteCodeInput" class="sr-only">Enter Invite Code</label>
type="text" <input type="text" id="joinInviteCodeInput" v-model="inviteCodeToJoin" class="form-input"
id="joinInviteCodeInput" placeholder="Enter Invite Code" required ref="joinInviteCodeInputRef" />
v-model="inviteCodeToJoin" </div>
placeholder="Enter Invite Code" <button type="submit" class="btn btn-secondary" :disabled="joiningGroup">
required <span v-if="joiningGroup" class="spinner-dots-sm" role="status"><span /><span /><span /></span>
ref="joinInviteCodeInputRef"
/>
</VFormField>
<VButton type="submit" variant="secondary" :disabled="joiningGroup">
<VSpinner v-if="joiningGroup" size="sm" />
Join Join
</VButton> </button>
</form> </form>
<!-- The error message is now handled by VFormField --> <p v-if="joinGroupFormError" class="form-error-text mt-1">{{ joinGroupFormError }}</p>
</div> </div>
</details> </details>
</div> </div>
<!-- Create Group Dialog --> <!-- Create Group Dialog -->
<VModal v-model="showCreateGroupDialog" title="Create New Group" @update:modelValue="val => !val && closeCreateGroupDialog()"> <div v-if="showCreateGroupDialog" class="modal-backdrop open" @click.self="closeCreateGroupDialog">
<form @submit.prevent="handleCreateGroup"> <div class="modal-container" ref="createGroupModalRef" role="dialog" aria-modal="true"
<VFormField label="Group Name" :error-message="createGroupFormError"> aria-labelledby="createGroupTitle">
<VInput <div class="modal-header">
type="text" <h3 id="createGroupTitle">Create New Group</h3>
v-model="newGroupName" <button class="close-button" @click="closeCreateGroupDialog" aria-label="Close">
placeholder="Enter group name" <svg class="icon" aria-hidden="true">
required <use xlink:href="#icon-close" />
id="newGroupNameInput" </svg>
ref="newGroupNameInputRef" </button>
/> </div>
</VFormField> <form @submit.prevent="handleCreateGroup">
<template #footer> <div class="modal-body">
<VButton variant="neutral" @click="closeCreateGroupDialog" type="button">Cancel</VButton> <div class="form-group">
<VButton type="submit" variant="primary" :disabled="creatingGroup"> <label for="newGroupNameInput" class="form-label">Group Name</label>
<VSpinner v-if="creatingGroup" size="sm" /> <input type="text" id="newGroupNameInput" v-model="newGroupName" class="form-input" required
Create ref="newGroupNameInputRef" />
</VButton> <p v-if="createGroupFormError" class="form-error-text">{{ createGroupFormError }}</p>
</template> </div>
</form> </div>
</VModal> <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 --> <!-- Create List Modal -->
<CreateListModal v-model="showCreateListModal" :groups="availableGroupsForModal" @created="onListCreated" /> <CreateListModal v-model="showCreateListModal" :groups="availableGroupsForModal" @created="onListCreated" />
@ -101,16 +113,9 @@ import { ref, onMounted, nextTick } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { apiClient, API_ENDPOINTS } from '@/config/api'; import { apiClient, API_ENDPOINTS } from '@/config/api';
import { useStorage } from '@vueuse/core'; 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 { useNotificationStore } from '@/stores/notifications';
import CreateListModal from '@/components/CreateListModal.vue'; 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 { interface Group {
id: number; id: number;
@ -130,13 +135,13 @@ const fetchError = ref<string | null>(null);
const showCreateGroupDialog = ref(false); const showCreateGroupDialog = ref(false);
const newGroupName = ref(''); const newGroupName = ref('');
const creatingGroup = ref(false); const creatingGroup = ref(false);
const newGroupNameInputRef = ref<InstanceType<typeof VInput> | null>(null); // Changed type to VInput instance const newGroupNameInputRef = ref<HTMLInputElement | null>(null);
// const createGroupModalRef = ref<HTMLElement | null>(null); // No longer needed const createGroupModalRef = ref<HTMLElement | null>(null);
const createGroupFormError = ref<string | null>(null); const createGroupFormError = ref<string | null>(null);
const inviteCodeToJoin = ref(''); const inviteCodeToJoin = ref('');
const joiningGroup = ref(false); 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 joinGroupFormError = ref<string | null>(null);
const showCreateListModal = ref(false); const showCreateListModal = ref(false);
@ -178,12 +183,7 @@ const openCreateGroupDialog = () => {
createGroupFormError.value = null; createGroupFormError.value = null;
showCreateGroupDialog.value = true; showCreateGroupDialog.value = true;
nextTick(() => { nextTick(() => {
// Attempt to focus VInput. This assumes VInput exposes a focus method newGroupNameInputRef.value?.focus();
// 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?.();
}); });
}; };
@ -191,12 +191,12 @@ const closeCreateGroupDialog = () => {
showCreateGroupDialog.value = false; showCreateGroupDialog.value = false;
}; };
// onClickOutside(createGroupModalRef, closeCreateGroupDialog); // Replaced by VModal's own handling onClickOutside(createGroupModalRef, closeCreateGroupDialog);
const handleCreateGroup = async () => { const handleCreateGroup = async () => {
if (!newGroupName.value.trim()) { if (!newGroupName.value.trim()) {
createGroupFormError.value = 'Group name is required'; createGroupFormError.value = 'Group name is required';
newGroupNameInputRef.value?.focus?.(); // Use VInput's focus method if available newGroupNameInputRef.value?.focus();
return; return;
} }
createGroupFormError.value = null; createGroupFormError.value = null;
@ -229,7 +229,7 @@ const handleCreateGroup = async () => {
const handleJoinGroup = async () => { const handleJoinGroup = async () => {
if (!inviteCodeToJoin.value.trim()) { if (!inviteCodeToJoin.value.trim()) {
joinGroupFormError.value = 'Invite code is required'; joinGroupFormError.value = 'Invite code is required';
joinInviteCodeInputRef.value?.focus?.(); // Use VInput's focus method if available joinInviteCodeInputRef.value?.focus();
return; return;
} }
joinGroupFormError.value = null; joinGroupFormError.value = null;