testapp: enhance room creation form with preferences handling and responsive design
This commit is contained in:
parent
6f19c35d43
commit
e7fba001e4
@ -6,20 +6,25 @@
|
|||||||
body,
|
body,
|
||||||
html {
|
html {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
margin: 0;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
margin: 0;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: #f8f9fa;
|
background-color: #f8f9fa;
|
||||||
|
padding: 0px;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 1000px;
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 25px;
|
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 {
|
.rooms-container {
|
||||||
@ -30,47 +35,130 @@ html {
|
|||||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
overflow: hidden;
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.create-room {
|
.create-room {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background: var(--secondary-color);
|
background: var(--secondary-color);
|
||||||
padding: 25px;
|
padding: 15px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
|
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);
|
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 {
|
.accordion-button:not(.collapsed) {
|
||||||
background-color: #357abd;
|
background-color: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu {
|
.accordion-button:focus {
|
||||||
min-width: 100%;
|
box-shadow: 0 0 0 0.25rem rgba(74, 144, 226, 0.25);
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-item {
|
.accordion-body {
|
||||||
cursor: pointer;
|
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 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -23,7 +23,11 @@
|
|||||||
<div class="rooms-list">
|
<div class="rooms-list">
|
||||||
<div class="mb-3 text-center">
|
<div class="mb-3 text-center">
|
||||||
<form action="/delete-all-rooms" method="post">
|
<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
|
Delete All Rooms
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
@ -129,37 +133,192 @@
|
|||||||
|
|
||||||
<!-- Create Room Section -->
|
<!-- Create Room Section -->
|
||||||
<div class="create-room">
|
<div class="create-room">
|
||||||
<h2 class="text-center text-primary">Create a new Room</h2>
|
<h2 class="text-center text-primary mb-3">Create a new Room</h2>
|
||||||
<p class="text-muted text-center">Generate a room from scratch</p>
|
<p class="text-muted text-center mb-4">Generate a room from scratch</p>
|
||||||
|
|
||||||
<form action="/room" method="post">
|
<form action="/room" method="post" class="d-flex flex-column h-100">
|
||||||
<div class="mb-3">
|
<!-- Basic Information -->
|
||||||
<label for="room-id-prefix" class="form-label">Room Prefix *</label>
|
<div class="form-section">
|
||||||
<input
|
<div class="mb-3">
|
||||||
type="text"
|
<label for="room-id-prefix" class="form-label"
|
||||||
name="roomIdPrefix"
|
>Room Prefix *</label
|
||||||
id="room-id-prefix"
|
>
|
||||||
class="form-control"
|
<input
|
||||||
placeholder="e.g. Team meeting"
|
type="text"
|
||||||
required
|
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>
|
||||||
|
|
||||||
<div class="mb-3">
|
<!-- Preferences Accordion -->
|
||||||
<label for="expiration-date" class="form-label"
|
<div class="preferences-accordion">
|
||||||
>Expiration Date</label
|
<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
|
Create Room
|
||||||
type="date"
|
</button>
|
||||||
name="autoDeletionDate"
|
|
||||||
id="expiration-date"
|
|
||||||
class="form-control"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="create-room-btn btn btn-primary w-100">
|
|
||||||
Create Room
|
|
||||||
</button>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -29,7 +29,9 @@ export const getHome = async (req: Request, res: Response) => {
|
|||||||
export const postCreateRoom = async (req: Request, res: Response) => {
|
export const postCreateRoom = async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { roomIdPrefix, autoDeletionDate } = req.body;
|
const { roomIdPrefix, autoDeletionDate } = req.body;
|
||||||
await createRoom({ roomIdPrefix, autoDeletionDate });
|
const preferences = processFormPreferences(req.body);
|
||||||
|
|
||||||
|
await createRoom({ roomIdPrefix, autoDeletionDate, preferences });
|
||||||
res.redirect('/');
|
res.redirect('/');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error creating room:', error);
|
console.error('Error creating room:', error);
|
||||||
@ -67,3 +69,27 @@ export const deleteAllRoomsCtrl = async (_req: Request, res: Response) => {
|
|||||||
return;
|
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;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user