refactor: Update GroupsPage to use standard HTML for now
This commit is contained in:
parent
679169e4fb
commit
74c73a9e8f
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user