refactor(frontend): simplify booking forms and convert to modals
- Simplify BookingForm: remove recurring bookings, templates, and attachments - Replace datetime-local with separate date/time inputs for better UX - Convert inline forms to modals (Admin spaces, Users, SpaceDetail) - Unify Create and Edit booking forms with identical styling and structure - Add Space field to Edit modal (read-only) - Fix calendar initial load and set week start to Monday - Translate all form labels and messages to Romanian Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,81 +1,10 @@
|
||||
<template>
|
||||
<div class="users">
|
||||
<h2>Admin Dashboard - User Management</h2>
|
||||
|
||||
<!-- Create/Edit Form -->
|
||||
<div class="card">
|
||||
<h3>{{ editingUser ? 'Edit User' : 'Create New User' }}</h3>
|
||||
<form @submit.prevent="handleSubmit" class="user-form">
|
||||
<div class="form-group">
|
||||
<label for="email">Email *</label>
|
||||
<input
|
||||
id="email"
|
||||
v-model="formData.email"
|
||||
type="email"
|
||||
required
|
||||
placeholder="user@example.com"
|
||||
:disabled="!!editingUser"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="full_name">Full Name *</label>
|
||||
<input
|
||||
id="full_name"
|
||||
v-model="formData.full_name"
|
||||
type="text"
|
||||
required
|
||||
placeholder="John Doe"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-group" v-if="!editingUser">
|
||||
<label for="password">Password *</label>
|
||||
<input
|
||||
id="password"
|
||||
v-model="formData.password"
|
||||
type="password"
|
||||
:required="!editingUser"
|
||||
placeholder="Minimum 8 characters"
|
||||
minlength="8"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="role">Role *</label>
|
||||
<select id="role" v-model="formData.role" required>
|
||||
<option value="user">User</option>
|
||||
<option value="admin">Admin</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="organization">Organization</label>
|
||||
<input
|
||||
id="organization"
|
||||
v-model="formData.organization"
|
||||
type="text"
|
||||
placeholder="Optional organization"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-primary" :disabled="loading">
|
||||
{{ editingUser ? 'Update' : 'Create' }}
|
||||
</button>
|
||||
<button
|
||||
v-if="editingUser"
|
||||
type="button"
|
||||
class="btn btn-secondary"
|
||||
@click="cancelEdit"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div v-if="error" class="error">{{ error }}</div>
|
||||
<div v-if="success" class="success">{{ success }}</div>
|
||||
<div class="page-header">
|
||||
<h2>Admin Dashboard - User Management</h2>
|
||||
<button class="btn btn-primary" @click="openCreateModal">
|
||||
Create New User
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Filters -->
|
||||
@@ -165,6 +94,79 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Create/Edit User Modal -->
|
||||
<div v-if="showFormModal" class="modal" @click.self="closeFormModal">
|
||||
<div class="modal-content">
|
||||
<h3>{{ editingUser ? 'Edit User' : 'Create New User' }}</h3>
|
||||
<form @submit.prevent="handleSubmit" class="user-form">
|
||||
<div class="form-group">
|
||||
<label for="email">Email *</label>
|
||||
<input
|
||||
id="email"
|
||||
v-model="formData.email"
|
||||
type="email"
|
||||
required
|
||||
placeholder="user@example.com"
|
||||
:disabled="!!editingUser"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="full_name">Full Name *</label>
|
||||
<input
|
||||
id="full_name"
|
||||
v-model="formData.full_name"
|
||||
type="text"
|
||||
required
|
||||
placeholder="John Doe"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-group" v-if="!editingUser">
|
||||
<label for="password">Password *</label>
|
||||
<input
|
||||
id="password"
|
||||
v-model="formData.password"
|
||||
type="password"
|
||||
:required="!editingUser"
|
||||
placeholder="Minimum 8 characters"
|
||||
minlength="8"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="role">Role *</label>
|
||||
<select id="role" v-model="formData.role" required>
|
||||
<option value="user">User</option>
|
||||
<option value="admin">Admin</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="organization">Organization</label>
|
||||
<input
|
||||
id="organization"
|
||||
v-model="formData.organization"
|
||||
type="text"
|
||||
placeholder="Optional organization"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="error" class="error">{{ error }}</div>
|
||||
<div v-if="success" class="success">{{ success }}</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-primary" :disabled="loading">
|
||||
{{ editingUser ? 'Update' : 'Create' }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary" @click="closeFormModal">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Reset Password Modal -->
|
||||
<div v-if="resetPasswordUser" class="modal" @click.self="closeResetPassword">
|
||||
<div class="modal-content">
|
||||
@@ -206,6 +208,7 @@ const loading = ref(false)
|
||||
const error = ref('')
|
||||
const success = ref('')
|
||||
const editingUser = ref<User | null>(null)
|
||||
const showFormModal = ref(false)
|
||||
const resetPasswordUser = ref<User | null>(null)
|
||||
const newPassword = ref('')
|
||||
const filterRole = ref('')
|
||||
@@ -259,8 +262,8 @@ const handleSubmit = async () => {
|
||||
success.value = 'User created successfully!'
|
||||
}
|
||||
|
||||
resetForm()
|
||||
await loadUsers()
|
||||
closeFormModal()
|
||||
|
||||
// Clear success message after 3 seconds
|
||||
setTimeout(() => {
|
||||
@@ -273,6 +276,11 @@ const handleSubmit = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const openCreateModal = () => {
|
||||
resetForm()
|
||||
showFormModal.value = true
|
||||
}
|
||||
|
||||
const startEdit = (user: User) => {
|
||||
editingUser.value = user
|
||||
formData.value = {
|
||||
@@ -282,10 +290,11 @@ const startEdit = (user: User) => {
|
||||
role: user.role,
|
||||
organization: user.organization || ''
|
||||
}
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' })
|
||||
showFormModal.value = true
|
||||
}
|
||||
|
||||
const cancelEdit = () => {
|
||||
const closeFormModal = () => {
|
||||
showFormModal.value = false
|
||||
resetForm()
|
||||
}
|
||||
|
||||
@@ -363,6 +372,19 @@ onMounted(() => {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.page-header h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
|
||||
Reference in New Issue
Block a user