Show actual user data on the edit page.

This commit is contained in:
Eli Ribble 2026-03-28 18:06:14 -07:00
parent 92ed974e4b
commit da7549eeda
No known key found for this signature in database
3 changed files with 102 additions and 114 deletions

View file

@ -23,8 +23,9 @@ type NoUserError struct{}
func (e NoUserError) Error() string { return "That user does not exist" }
type User struct {
Active bool `json:"active"`
DisplayName string `json:"display_name"`
ID int `json:"-"`
ID int `json:"id"`
Initials string `json:"initials"`
Notifications []Notification `json:"notifications"`
NotificationCounts UserNotificationCounts `json:"notification_counts"`
@ -32,6 +33,7 @@ type User struct {
PasswordHash string `json:"-"`
PasswordHashType string `json:"-"`
Role string `json:"role"`
Tags []string `json:"tags"`
URI string `json:"uri"`
Username string `json:"username"`
@ -50,6 +52,7 @@ func (u User) HasRoot() bool {
}
func newUser(ctx context.Context, org Organization, user *models.User) User {
u := User{
Active: true,
DisplayName: user.DisplayName,
ID: int(user.ID),
Initials: extractInitials(user.DisplayName),
@ -59,6 +62,7 @@ func newUser(ctx context.Context, org Organization, user *models.User) User {
PasswordHash: user.PasswordHash,
PasswordHashType: string(user.PasswordHashType),
Role: user.Role.String(),
Tags: []string{},
URI: fmt.Sprintf("/user/%d", user.ID),
Username: user.Username,

View file

@ -19,9 +19,11 @@ export const useUsersStore = defineStore("users", () => {
});
// Actions
function byID(id: int) {
return _byID.value.get(id);
const result = _byID.value.get(id);
console.log("user", id, result);
return result;
}
async function fetchAll() {
async function fetchAll(): Promise<User[]> {
const userStore = useUserStore();
if (userStore.urls == null) {
throw new Error("can't fetch without user URL data");
@ -44,6 +46,7 @@ export const useUsersStore = defineStore("users", () => {
for (const u of data.users) {
_byID.value.set(u.id, u);
}
return data.users;
} catch (err) {
console.error("Error loading users:", err);
throw err;

View file

@ -40,7 +40,7 @@ pre {
<div class="card-header bg-primary text-white">
<h4 class="mb-0">User Configuration</h4>
</div>
<div class="card-body">
<div v-if="user" class="card-body">
<!-- Avatar Section -->
<div class="row mb-4">
<div class="col-md-12">
@ -88,7 +88,7 @@ pre {
</label>
<input
id="displayName"
v-model="user.displayName"
v-model="user.display_name"
type="text"
class="form-control"
placeholder="Enter display name"
@ -230,15 +230,8 @@ pre {
</div>
</div>
</div>
</div>
<!-- Preview Card -->
<div class="card shadow-sm mt-4">
<div class="card-header bg-secondary text-white">
<h5 class="mb-0">Preview</h5>
</div>
<div class="card-body">
<pre class="mb-0">{{ user }}</pre>
<div v-else>
<p>loading</p>
</div>
</div>
</div>
@ -246,8 +239,9 @@ pre {
</div>
</template>
<script lang="ts">
import { defineComponent, ref, reactive } from "vue";
<script setup lang="ts">
import { computed, defineComponent, onMounted, ref, reactive } from "vue";
import { useUsersStore } from "@/store/users";
interface User {
avatar: string;
@ -263,112 +257,99 @@ interface Role {
label: string;
}
export default defineComponent({
name: "UserConfiguration",
setup() {
const fileInput = ref<HTMLInputElement | null>(null);
const selectedTag = ref<string>("");
interface Props {
id: int;
}
const defaultAvatar =
"https://via.placeholder.com/150/cccccc/666666?text=No+Avatar";
const fileInput = ref<HTMLInputElement | null>(null);
const props = defineProps<Props>();
const selectedTag = ref<string>("");
const usersStore = useUsersStore();
const user = ref<User | null>(null);
const user = reactive<User>({
avatar: "",
displayName: "John Doe",
username: "johndoe123",
role: "tech1",
status: "active",
tags: ["warrant"],
});
const defaultAvatar =
"https://via.placeholder.com/150/cccccc/666666?text=No+Avatar";
const availableRoles: Role[] = [
{ value: "manager", label: "Manager" },
{ value: "owner", label: "Owner" },
{ value: "tech1", label: "Tech 1" },
{ value: "tech2", label: "Tech 2" },
{ value: "tech3", label: "Tech 3" },
];
const availableRoles: Role[] = [
{ value: "account-owner", label: "Account Owner" },
{ value: "manager", label: "Manager" },
{ value: "tech1", label: "Tech 1" },
{ value: "tech2", label: "Tech 2" },
{ value: "tech3", label: "Tech 3" },
];
const availableTags: string[] = [
"warrant",
"drone pilot",
"certified",
"supervisor",
"field ops",
];
const availableTags: string[] = [
"warrant",
"drone pilot",
"certified",
"supervisor",
"field ops",
];
const triggerFileInput = () => {
fileInput.value?.click();
const triggerFileInput = () => {
fileInput.value?.click();
};
const handleAvatarChange = (event: Event) => {
const target = event.target as HTMLInputElement;
const file = target.files?.[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
user.avatar = e.target?.result as string;
};
reader.readAsDataURL(file);
}
};
const handleAvatarChange = (event: Event) => {
const target = event.target as HTMLInputElement;
const file = target.files?.[0];
const removeAvatar = () => {
user.avatar = "";
if (fileInput.value) {
fileInput.value.value = "";
}
};
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
user.avatar = e.target?.result as string;
};
reader.readAsDataURL(file);
const addTag = () => {
if (selectedTag.value && !user.tags.includes(selectedTag.value)) {
user.tags.push(selectedTag.value);
selectedTag.value = "";
}
};
const removeTag = (tag: string) => {
const index = user.tags.indexOf(tag);
if (index > -1) {
user.tags.splice(index, 1);
}
};
const saveChanges = () => {
// Implement save logic here
console.log("Saving user configuration:", user);
alert("User configuration saved successfully!");
};
const cancelChanges = () => {
// Implement cancel/reset logic here
console.log("Canceling changes");
if (
confirm(
"Are you sure you want to cancel? All unsaved changes will be lost.",
)
) {
// Reset to original values or navigate away
window.history.back();
}
};
onMounted(() => {
usersStore.fetchAll().then((users) => {
for (const u of users) {
if (u.id == props.id) {
user.value = u;
console.log("User set to", u);
}
};
const removeAvatar = () => {
user.avatar = "";
if (fileInput.value) {
fileInput.value.value = "";
}
};
const addTag = () => {
if (selectedTag.value && !user.tags.includes(selectedTag.value)) {
user.tags.push(selectedTag.value);
selectedTag.value = "";
}
};
const removeTag = (tag: string) => {
const index = user.tags.indexOf(tag);
if (index > -1) {
user.tags.splice(index, 1);
}
};
const saveChanges = () => {
// Implement save logic here
console.log("Saving user configuration:", user);
alert("User configuration saved successfully!");
};
const cancelChanges = () => {
// Implement cancel/reset logic here
console.log("Canceling changes");
if (
confirm(
"Are you sure you want to cancel? All unsaved changes will be lost.",
)
) {
// Reset to original values or navigate away
window.history.back();
}
};
return {
user,
fileInput,
selectedTag,
defaultAvatar,
availableRoles,
availableTags,
triggerFileInput,
handleAvatarChange,
removeAvatar,
addTag,
removeTag,
saveChanges,
cancelChanges,
};
},
}
});
});
</script>