-
+
+
+
diff --git a/frontend/components/ui/dialog-provider/utils.ts b/frontend/components/ui/dialog-provider/utils.ts
index 114d2a97..1cd73de5 100644
--- a/frontend/components/ui/dialog-provider/utils.ts
+++ b/frontend/components/ui/dialog-provider/utils.ts
@@ -30,6 +30,7 @@ export enum DialogID {
UpdateLabel = "update-label",
UpdateLocation = "update-location",
CreateInvite = "create-invite",
+ EditUser = "edit-user",
UpdateTemplate = "update-template",
ItemChangeDetails = "item-table-updater",
}
@@ -57,6 +58,7 @@ export type DialogParamsMap = {
attachmentId: string;
};
[DialogID.CreateItem]?: { product?: BarcodeProduct };
+ [DialogID.EditUser]?: { userId?: string };
[DialogID.ProductImport]?: { barcode?: string };
[DialogID.EditMaintenance]:
| { type: "create"; itemId: string | string[] }
@@ -78,6 +80,7 @@ export type DialogResultMap = {
[DialogID.EditMaintenance]?: boolean;
[DialogID.CreateInvite]?: boolean;
[DialogID.ItemChangeDetails]?: boolean;
+ [DialogID.EditUser]?: boolean;
};
/** Helpers to split IDs by requirement */
diff --git a/frontend/pages/admin.vue b/frontend/pages/admin.vue
index cdf6c244..319dd639 100644
--- a/frontend/pages/admin.vue
+++ b/frontend/pages/admin.vue
@@ -13,10 +13,15 @@
import BaseSectionHeader from "@/components/Base/SectionHeader.vue";
import MdiPencil from "~icons/mdi/pencil";
import MdiDelete from "~icons/mdi/delete";
+ import MdiCheck from "~icons/mdi/check";
+ import MdiClose from "~icons/mdi/close";
// import MdiOpenInNew from "~icons/mdi/open-in-new";
// Badge component for collections display
import { Badge } from "@/components/ui/badge";
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import UserFormDialog from "@/components/Admin/UserFormDialog.vue";
+ import { useDialog } from "@/components/ui/dialog-provider";
+ import { DialogID } from "@/components/ui/dialog-provider/utils";
import { api, type Collection as MockCollection, type User } from "~/mock/collections";
@@ -35,10 +40,7 @@
});
});
- const editing = ref
(null);
- const showForm = ref(false);
- const newPassword = ref("");
- const editingCollectionIds = ref([]);
+ const { openDialog } = useDialog();
const confirm = useConfirm();
const { t } = useI18n();
@@ -55,61 +57,26 @@
}
function openAdd() {
- editing.value = { id: String(Date.now()), name: "", email: "", role: "user", password_set: false, collections: [] };
- newPassword.value = "";
- editingCollectionIds.value = [];
- showForm.value = true;
+ openDialog(DialogID.EditUser, {
+ onClose: result => {
+ if (result) {
+ users.value = api.getUsers();
+ collections.value = api.getCollections();
+ }
+ },
+ });
}
function openEdit(u: User) {
- editing.value = { ...u };
- editingCollectionIds.value = (u.collections ?? []).map(c => c.id);
- newPassword.value = "";
- showForm.value = true;
- }
-
- function saveUser() {
- if (!editing.value) return;
- // basic validation
- if (!editing.value.name.trim() || !editing.value.email.trim()) {
- // keep UX simple: alert for now
- // Replace with a nicer notification component when available
- alert("Name and email are required");
- return;
- }
-
- // apply password flag if new password was set locally
- if (newPassword.value && editing.value) editing.value.password_set = true;
-
- const existing = api.getUser(editing.value.id);
- if (existing) {
- // update only scalar fields; collections are managed via the add/remove API
- const updated = {
- ...existing,
- name: editing.value.name,
- email: editing.value.email,
- role: editing.value.role,
- password_set: editing.value.password_set,
- } as User;
- api.updateUser(updated);
- } else {
- // create user without collections first, then add memberships
- const toCreate = { ...editing.value, collections: [] } as User;
- const created = api.addUser(toCreate);
- editingCollectionIds.value.forEach(id => api.addUserToCollection(created.id, id, "viewer"));
- }
-
- // refresh local cache
- users.value = api.getUsers();
-
- editing.value = null;
- showForm.value = false;
- // TODO: call backend API to persist changes when available
- }
-
- function cancelForm() {
- editing.value = null;
- showForm.value = false;
+ openDialog(DialogID.EditUser, {
+ params: { userId: u.id },
+ onClose: result => {
+ if (result) {
+ users.value = api.getUsers();
+ collections.value = api.getCollections();
+ }
+ },
+ });
}
async function confirmDelete(u: User) {
@@ -130,17 +97,13 @@
return col ? col.name : id;
}
- function onUpdateEditing(val: User | null) {
- editing.value = val;
+ function roleVariant(role: string | undefined) {
+ if (role === "owner") return "default";
+ if (role === "admin") return "secondary";
+ return "outline";
}
- function onUpdateEditingCollectionIds(val: string[]) {
- editingCollectionIds.value = val;
- }
-
- function onUpdateNewPassword(val: string) {
- newPassword.value = val;
- }
+ // dialog handles editing state now via dialog provider
@@ -156,12 +119,12 @@
- {{ t("global.name") }}
- {{ t("global.email") }}
- Is Admin
- Collections
- Auth
- {{ t("global.details") }}
+ {{ t("global.name") }}
+ {{ t("global.email") }}
+ Is Admin
+ Collections
+ {{ t("global.details") }}
+
@@ -170,24 +133,40 @@
{{ u.name }}
{{ u.email }}
-
- {{ u.role === "admin" ? "Yes" : "No" }}
+
+
+
+
+
- {{ collectionName(c.id) }}({{ c.role }})
+
+
+
+
+ {{
+ collectionName(c.id)
+ }}
+
+
+ {{ c.role }}
+
+
+
+
-
-
- {{ authType(u) }}
+
+
+ {{ authType(u) }}
+
-
-
+
+
@@ -215,18 +194,6 @@
- (collections = api.getCollections())"
- />
+