testapp: enhance room creation form with preferences handling and responsive design

This commit is contained in:
Carlos Santos 2025-06-09 17:50:58 +02:00
parent 6f19c35d43
commit e7fba001e4
3 changed files with 333 additions and 60 deletions

View File

@ -6,20 +6,25 @@
body,
html {
height: 100vh;
margin: 0;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin: 0;
background-color: #f8f9fa;
padding: 0px;
box-sizing: border-box;
}
.container {
width: 100%;
max-width: 1000px;
max-width: 1200px;
margin: 0 auto;
display: flex;
gap: 25px;
max-height: 450px;
min-height: calc(80vh - 40px);
max-height: calc(80vh - 40px);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.rooms-container {
@ -30,47 +35,130 @@ html {
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
}
.rooms-header {
position: sticky;
top: 0;
background: white;
z-index: 10;
padding-bottom: 10px;
border-bottom: 2px solid var(--primary-color);
}
.rooms-list {
overflow-y: auto;
height: 100%;
max-height: 100%;
padding-right: 10px;
overflow: hidden;
}
.create-room {
flex: 1;
background: var(--secondary-color);
padding: 25px;
padding: 15px;
border-radius: 10px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
overflow: hidden;
}
.create-room p,
.create-room h2 {
margin-bottom: 0 !important ;
font-size: 0.9rem;
}
.create-room h2 {
font-size: 1.1rem; /* Smaller title */
}
.btn-primary {
/* Collapsible sections for room creation form */
.preferences-accordion {
flex: 1;
overflow-y: auto;
}
.accordion-item {
border: none;
margin-bottom: 0.25rem;
}
.accordion-button {
background-color: var(--primary-color);
border-color: var(--primary-color);
color: white;
border-radius: 0.25rem !important; /* Smaller radius */
font-weight: 500; /* Less bold */
font-size: 0.8rem; /* Smaller text */
padding: 0.4rem 0.8rem; /* Much smaller padding */
min-height: auto; /* Remove default height */
}
.btn-primary:hover {
background-color: #357abd;
.accordion-button:not(.collapsed) {
background-color: var(--primary-color);
color: white;
box-shadow: none;
}
.dropdown-menu {
min-width: 100%;
text-align: center;
.accordion-button:focus {
box-shadow: 0 0 0 0.25rem rgba(74, 144, 226, 0.25);
}
.dropdown-item {
cursor: pointer;
.accordion-body {
padding: 0.5rem; /* Much smaller padding */
background-color: #f8f9fa;
font-size: 0.8rem; /* Smaller text */
}
form-label {
font-size: 0.8rem; /* Smaller labels */
margin-bottom: 0.25rem;
}
.form-control,
.form-select {
font-size: 0.8rem; /* Smaller inputs */
padding: 0.25rem 0.5rem; /* Smaller padding */
}
.form-check {
margin-bottom: 0.25rem; /* Smaller spacing */
}
.form-check-label {
font-size: 0.8rem; /* Smaller text */
}
.form-text {
font-size: 0.7rem !important; /* Much smaller help text */
margin-top: 0.125rem;
}
#recording-access-section {
background-color: rgba(13, 110, 253, 0.1);
padding: 0.4rem; /* Smaller padding */
border-radius: 0.25rem;
border-left: 2px solid var(--primary-color); /* Thinner border */
margin-top: 0.25rem;
}
/* Compact button */
.create-room-btn {
font-size: 0.85rem; /* Smaller button text */
padding: 0.4rem 0.8rem; /* Smaller button */
margin-top: 0.5rem; /* Less top margin */
}
/* Responsive adjustments */
@media (max-height: 600px) {
.container {
flex-direction: column;
max-height: none;
min-height: auto;
}
.create-room {
max-height: 350px; /* Smaller max height */
}
}
@media (max-width: 768px) {
.container {
flex-direction: column;
max-height: none;
gap: 15px;
}
body,
html {
padding: 10px;
}
.create-room {
padding: 10px; /* Even smaller on mobile */
}
}

View File

@ -23,7 +23,11 @@
<div class="rooms-list">
<div class="mb-3 text-center">
<form action="/delete-all-rooms" method="post">
<button type="submit" class="btn btn-danger btn-sm" id="delete-all-rooms">
<button
type="submit"
class="btn btn-danger btn-sm"
id="delete-all-rooms"
>
Delete All Rooms
</button>
</form>
@ -129,37 +133,192 @@
<!-- Create Room Section -->
<div class="create-room">
<h2 class="text-center text-primary">Create a new Room</h2>
<p class="text-muted text-center">Generate a room from scratch</p>
<h2 class="text-center text-primary mb-3">Create a new Room</h2>
<p class="text-muted text-center mb-4">Generate a room from scratch</p>
<form action="/room" method="post">
<div class="mb-3">
<label for="room-id-prefix" class="form-label">Room Prefix *</label>
<input
type="text"
name="roomIdPrefix"
id="room-id-prefix"
class="form-control"
placeholder="e.g. Team meeting"
required
/>
<form action="/room" method="post" class="d-flex flex-column h-100">
<!-- Basic Information -->
<div class="form-section">
<div class="mb-3">
<label for="room-id-prefix" class="form-label"
>Room Prefix *</label
>
<input
type="text"
name="roomIdPrefix"
id="room-id-prefix"
class="form-control"
placeholder="e.g. Team meeting"
required
/>
</div>
<div class="mb-3">
<label for="expiration-date" class="form-label"
>Expiration Date</label
>
<input
type="date"
name="autoDeletionDate"
id="expiration-date"
class="form-control"
/>
</div>
</div>
<div class="mb-3">
<label for="expiration-date" class="form-label"
>Expiration Date</label
<!-- Preferences Accordion -->
<div class="preferences-accordion">
<div class="accordion" id="preferencesAccordion">
<!-- Chat Preferences -->
<div class="accordion-item">
<h2 class="accordion-header">
<button
class="accordion-button"
type="button"
data-bs-toggle="collapse"
data-bs-target="#chatCollapse"
aria-expanded="true"
aria-controls="chatCollapse"
data-testid="chat-preferences-toggle"
>
Chat Settings
</button>
</h2>
<div
id="chatCollapse"
class="accordion-collapse collapse show"
data-bs-parent="#preferencesAccordion"
>
<div class="accordion-body">
<div class="form-check">
<input
type="checkbox"
name="preferences.chatPreferences.enabled"
id="chat-enabled"
class="form-check-input"
checked
data-testid="chat-enabled-checkbox"
/>
<label for="chat-enabled" class="form-check-label">
Enable Chat
</label>
</div>
</div>
</div>
</div>
<!-- Recording Preferences -->
<div class="accordion-item">
<h2 class="accordion-header">
<button
class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
data-bs-target="#recordingCollapse"
aria-expanded="false"
aria-controls="recordingCollapse"
data-testid="recording-preferences-toggle"
>
Recording Settings
</button>
</h2>
<div
id="recordingCollapse"
class="accordion-collapse collapse"
data-bs-parent="#preferencesAccordion"
>
<div class="accordion-body">
<div class="form-check mb-2">
<input
type="checkbox"
name="preferences.recordingPreferences.enabled"
id="recording-enabled"
class="form-check-input"
checked
data-testid="recording-enabled-checkbox"
/>
<label for="recording-enabled" class="form-check-label">
Enable Recording
</label>
</div>
<div id="recording-access-section">
<label for="recording-access" class="form-label"
>Recording Access Level</label
>
<select
name="preferences.recordingPreferences.allowAccessTo"
id="recording-access"
class="form-select"
data-testid="recording-access-select"
>
<option value="admin">Admin Only</option>
<option value="admin-moderator">
Admin & Moderator
</option>
<option value="admin-moderator-publisher" selected>
Admin, Moderator & Publisher
</option>
<option value="public">Public Access</option>
</select>
</div>
</div>
</div>
</div>
<!-- Virtual Background Preferences -->
<div class="accordion-item">
<h2 class="accordion-header">
<button
class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
data-bs-target="#backgroundCollapse"
aria-expanded="false"
aria-controls="backgroundCollapse"
data-testid="background-preferences-toggle"
>
Virtual Background Settings
</button>
</h2>
<div
id="backgroundCollapse"
class="accordion-collapse collapse"
data-bs-parent="#preferencesAccordion"
>
<div class="accordion-body">
<div class="form-check">
<input
type="checkbox"
name="preferences.virtualBackgroundPreferences.enabled"
id="virtual-background-enabled"
class="form-check-input"
checked
data-testid="virtual-background-enabled-checkbox"
/>
<label
for="virtual-background-enabled"
class="form-check-label"
>
Enable Virtual Backgrounds
</label>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Create Button - Always visible -->
<div class="mt-auto pt-3">
<button
type="submit"
class="create-room-btn btn btn-primary w-100"
data-testid="create-room-button"
>
<input
type="date"
name="autoDeletionDate"
id="expiration-date"
class="form-control"
/>
Create Room
</button>
</div>
<button type="submit" class="create-room-btn btn btn-primary w-100">
Create Room
</button>
</form>
</div>
</div>

View File

@ -29,7 +29,9 @@ export const getHome = async (req: Request, res: Response) => {
export const postCreateRoom = async (req: Request, res: Response) => {
try {
const { roomIdPrefix, autoDeletionDate } = req.body;
await createRoom({ roomIdPrefix, autoDeletionDate });
const preferences = processFormPreferences(req.body);
await createRoom({ roomIdPrefix, autoDeletionDate, preferences });
res.redirect('/');
} catch (error) {
console.error('Error creating room:', error);
@ -67,3 +69,27 @@ export const deleteAllRoomsCtrl = async (_req: Request, res: Response) => {
return;
}
};
/**
* Converts flat form data to nested MeetRoomPreferences object
*/
const processFormPreferences = (body: any): any => {
const preferences = {
chatPreferences: {
enabled: body['preferences.chatPreferences.enabled'] === 'on'
},
recordingPreferences: {
enabled: body['preferences.recordingPreferences.enabled'] === 'on',
// Only include allowAccessTo if recording is enabled
...(body['preferences.recordingPreferences.enabled'] === 'on' && {
allowAccessTo: body['preferences.recordingPreferences.allowAccessTo'] || 'admin-moderator-publisher'
})
},
virtualBackgroundPreferences: {
enabled: body['preferences.virtualBackgroundPreferences.enabled'] === 'on'
}
};
return preferences;
}