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">
<!-- <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">
<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
</VButton>
</template>
</VCard>
</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()">
<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">
<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" />
<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
</VButton>
</template>
</button>
</div>
</form>
</VModal>
</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;