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">
|
<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;
|
||||||
|
Loading…
Reference in New Issue
Block a user