Skip to content

Commit e3dc6f1

Browse files
committed
Update BookingPage appointment info styles
1 parent 9954f6c commit e3dc6f1

File tree

8 files changed

+181
-125
lines changed

8 files changed

+181
-125
lines changed

frontend/src/locales/de.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,7 @@
554554
"completelyRemoveUser": "Hier wird ein Benutzer vollständig aus Thunderbird Appointment entfernt, einschließlich aller Benutzerdaten. Diese Funktion bitte nicht ausführen, wenn es keine Aufforderung dafür gab.",
555555
"disableAccountFirst": "Das Konto muss zunächst deaktiviert sein."
556556
},
557+
"bookATimeToMeetWith": "Buche einen Zeitpunkt um mit {name} zu treffen",
557558
"calendarDeletionWarning": "Wenn die Verbindung zu diesem Kalender getrennt wird, werden alle Termine und Zeitpläne aus Thunderbird Appointment entfernt. Es werden keine Termine entfernt, die derzeit in diesem Kalender gespeichert sind.",
558559
"chooseDateAndTime": "Wähle Tag und Zeit für ein Treffen.",
559560
"connectZoom": "Du kannst dein Zoom-Konto verbinden, um Besprechungen direkt mit einer Zoom-Einladung zu erstellen.",
@@ -575,7 +576,6 @@
575576
"login": {
576577
"continueToFxa": "Bitte die E-Mail-Adresse des Mozilla-Kontos eingeben."
577578
},
578-
"nameIsInvitingYou": "{name} lädt dich ein zu",
579579
"ownerNeedsToConfirmBooking": "Wenn diese Option aktiviert ist, müssen Buchungen dieses Zeitplans bestätigt oder ablehnt werden. Wenn diese Option deaktiviert ist, werden alle Zeiten automatisch bestätigt.",
580580
"preferredEmailHelp": "Die E-Mail-Adresse festlegen, die für ausgehende Kommunikation in Kalenderereignissen verwendet werden soll.",
581581
"recipientsCanScheduleBetween": "Empfänger können einen Termin zwischen {earliest} und {farthest} ab dem aktuellen Zeitpunkt wählen. ",

frontend/src/locales/en.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@
451451
"timeFormat": "Time Format",
452452
"timeOfTheEvent": "Time of the event:",
453453
"timeUpdated": "Time Updated",
454-
"timeZone": "Time Zone",
454+
"timeZone": "Timezone",
455455
"title": "Title",
456456
"to": "to",
457457
"today": "Today",
@@ -557,6 +557,7 @@
557557
"completelyRemoveUser": "This will completely remove a user from Thunderbird Appointment, including all of their user data. Don't do this unless you're told to.",
558558
"disableAccountFirst": "You must disable the account first."
559559
},
560+
"bookATimeToMeetWith": "Book a time to meet with {name}",
560561
"calendarDeletionWarning": "Removing this calendar will remove all appointments and schedules from Thunderbird Appointment. Any confirmed events currently stored in your calendar will not be removed.",
561562
"chooseDateAndTime": "Choose when to meet.",
562563
"connectZoom": "Connect your Zoom account to generate instant meeting invites for each booking.",
@@ -578,7 +579,6 @@
578579
"login": {
579580
"continueToFxa": "Enter your email above to continue to Mozilla Accounts"
580581
},
581-
"nameIsInvitingYou": "{name} is inviting you to",
582582
"ownerNeedsToConfirmBooking": "When this option is active, you will be required to confirm or decline times booked on your schedule. When this option is deactivated, all times will automatically be confirmed.",
583583
"preferredEmailHelp": "Set the email you'll use for out-going communication. This will be used in calendar events and emails.",
584584
"recipientsCanScheduleBetween": "Recipients can schedule a {duration} appointment between {earliest} and {farthest} ahead of time.",

frontend/src/views/BookerView/components/BookingViewSlotSelection.vue

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<script setup lang="ts">
22
import { inject, computed } from 'vue';
33
import { storeToRefs } from 'pinia';
4+
import { Dayjs } from 'dayjs';
5+
import { useI18n } from 'vue-i18n';
6+
import { PhGlobe } from '@phosphor-icons/vue';
47
58
import { useBookingViewStore } from '@/stores/booking-view-store';
69
import { useCalendarStore } from '@/stores/calendar-store';
@@ -10,8 +13,9 @@ import { dayjsKey } from '@/keys';
1013
import WeekPicker from '@/views/DashboardView/components/WeekPicker.vue';
1114
import WeekCalendar from '@/views/DashboardView/components/WeekCalendar.vue';
1215
import SlotSelectionAside from './SlotSelectionAside.vue';
13-
import { Dayjs } from 'dayjs';
16+
import SlotSelectionHeader from './SlotSelectionHeader.vue';
1417
18+
const { t } = useI18n();
1519
const calendarStore = useCalendarStore();
1620
const { appointment, activeDate, selectedEvent } = storeToRefs(useBookingViewStore());
1721
const dj = inject(dayjsKey);
@@ -22,6 +26,8 @@ const activeDateRange = computed(() => ({
2226
end: activeDate.value.endOf('week').format('YYYY-MM-DD'),
2327
}));
2428
29+
const timezone = computed(() => dj.tz.guess());
30+
2531
/**
2632
* Select a specific time slot
2733
* @param day string
@@ -53,21 +59,32 @@ async function onDateChange(dateObj: TimeFormatted) {
5359
</script>
5460

5561
<template>
56-
<div v-if="appointment" class="booker-view-container">
57-
<div class="calendar-container">
58-
<week-picker
59-
:active-date-range="activeDateRange"
60-
:onDateChange="onDateChange"
61-
/>
62-
<week-calendar
63-
:active-date-range="activeDateRange"
64-
:selectable-slots="appointment.slots"
65-
@event-selected="selectEvent"
66-
/>
62+
<template v-if="appointment">
63+
<slot-selection-header />
64+
65+
<div class="booker-view-container">
66+
<div class="calendar-container">
67+
<div class="week-picker-container">
68+
<week-picker
69+
:active-date-range="activeDateRange"
70+
:onDateChange="onDateChange"
71+
/>
72+
</div>
73+
<week-calendar
74+
:active-date-range="activeDateRange"
75+
:selectable-slots="appointment.slots"
76+
@event-selected="selectEvent"
77+
/>
78+
79+
<div class="calendar-footer">
80+
<ph-globe size="16" />
81+
<span>{{ t('label.timeZone') }}: {{ timezone }}</span>
82+
</div>
83+
</div>
84+
85+
<slot-selection-aside />
6786
</div>
68-
69-
<slot-selection-aside />
70-
</div>
87+
</template>
7188
</template>
7289

7390
<style scoped>
@@ -76,11 +93,23 @@ async function onDateChange(dateObj: TimeFormatted) {
7693
.booker-view-container {
7794
display: flex;
7895
flex-direction: column;
79-
gap: 1rem;
96+
gap: 2rem;
8097
}
8198
8299
.calendar-container {
83100
width: 100%;
101+
102+
.week-picker-container {
103+
margin-block-end: 2rem;
104+
}
105+
106+
.calendar-footer {
107+
display: flex;
108+
align-items: center;
109+
gap: 0.5rem;
110+
margin-block: 1.25rem;
111+
font-size: 0.6875rem;
112+
}
84113
}
85114
86115
@media (--md) {

frontend/src/views/BookerView/components/SlotSelectionAside.vue

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -111,23 +111,6 @@ const bookEvent = async () => {
111111

112112
<template>
113113
<aside>
114-
<p class="invitation-text" data-testid="booking-view-inviting-you-text">
115-
{{ t('text.nameIsInvitingYou', { name: appointment.owner_name }) }}
116-
</p>
117-
<h1 class="appointment-title" data-testid="booking-view-title-text">
118-
{{ appointment.title }}
119-
</h1>
120-
<p v-if="appointment.details" class="appointment-details">
121-
{{ appointment.details }}
122-
</p>
123-
<div class="timezone-section">
124-
<span class="timezone-label">{{ t('label.timeZone') }}:</span>
125-
<div class="timezone-display">
126-
<ph-globe size="24" />
127-
{{ timezone }}
128-
</div>
129-
</div>
130-
131114
<template v-if="selectedEvent">
132115
<div class="appointment-card">
133116
<h3>{{ t('label.bookingDetails') }}</h3>
@@ -183,48 +166,6 @@ const bookEvent = async () => {
183166
@import '@/assets/styles/custom-media.pcss';
184167
185168
aside {
186-
.invitation-text {
187-
margin-bottom: 0.825rem;
188-
font-size: 0.825rem;
189-
font-weight: 600;
190-
color: var(--colour-ti-muted);
191-
}
192-
193-
.appointment-title {
194-
margin-bottom: 0.825rem;
195-
font-size: 1.725rem;
196-
line-height: 2.25rem;
197-
color: var(--colour-ti-base);
198-
}
199-
200-
.appointment-details {
201-
margin-bottom: 1.5rem;
202-
color: var(--colour-ti-base);
203-
}
204-
205-
.timezone-section {
206-
margin-bottom: 1.5rem;
207-
display: flex;
208-
flex-direction: row;
209-
align-items: center;
210-
gap: 1rem;
211-
212-
.timezone-label {
213-
font-size: 0.875rem;
214-
line-height: 1.75rem;
215-
color: var(--colour-ti-base);
216-
}
217-
218-
.timezone-display {
219-
font-size: 0.875rem;
220-
line-height: 1.25rem;
221-
color: var(--colour-accent-teal);
222-
display: flex;
223-
align-items: center;
224-
gap: 0.5rem;
225-
}
226-
}
227-
228169
.appointment-card {
229170
display: flex;
230171
flex-direction: column;
@@ -298,10 +239,6 @@ aside {
298239
position: sticky;
299240
top: 5rem;
300241
width: 470px;
301-
302-
.timezone-section {
303-
flex-direction: row;
304-
}
305242
}
306243
}
307244
</style>
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<script setup lang="ts">
2+
import { storeToRefs } from 'pinia';
3+
import { useI18n } from 'vue-i18n';
4+
import { PhClock, PhMapPin } from '@phosphor-icons/vue';
5+
import { useBookingViewStore } from '@/stores/booking-view-store';
6+
7+
const { t } = useI18n();
8+
const calendarStore = useBookingViewStore();
9+
10+
const { appointment } = storeToRefs(calendarStore);
11+
12+
console.log(appointment.value);
13+
</script>
14+
15+
<template>
16+
<div class="booking-header">
17+
<div class="booking-header-title-container">
18+
<h2 data-testid="booking-view-book-a-time-to-meet-with-text">
19+
{{ t('text.bookATimeToMeetWith', { name: appointment.owner_name }) }}
20+
</h2>
21+
22+
<div class="booking-header-time-place">
23+
<div class="booking-header-time-place-item">
24+
<ph-clock size="16" />
25+
<span>{{ appointment.slot_duration }} minutes</span>
26+
</div>
27+
<div class="booking-header-time-place-item">
28+
<ph-map-pin size="16" />
29+
<span>Online meeting</span>
30+
</div>
31+
</div>
32+
</div>
33+
34+
<strong data-testid="booking-view-title-text">{{ appointment.title }}</strong>
35+
<p v-if="appointment.details">{{ appointment.details }}</p>
36+
</div>
37+
</template>
38+
39+
<style scoped>
40+
.booking-header {
41+
margin-block-end: 2rem;
42+
font-family: Inter, sans-serif;
43+
44+
p, strong {
45+
line-height: 1.32;
46+
color: var(--colour-ti-base);
47+
}
48+
49+
strong {
50+
font-weight: 700;
51+
}
52+
53+
.booking-header-title-container {
54+
display: flex;
55+
align-items: center;
56+
justify-content: space-between;
57+
max-width: calc(100% - 370px); /* Aligns with the slot-selection-aside width */
58+
margin-block-end: 1rem;
59+
60+
h2 {
61+
font-size: 1.5rem;
62+
font-weight: 400;
63+
color: var(--colour-ti-highlight);
64+
}
65+
66+
.booking-header-time-place {
67+
display: flex;
68+
align-items: center;
69+
gap: 2rem;
70+
71+
.booking-header-time-place-item {
72+
display: flex;
73+
align-items: center;
74+
gap: 0.5rem;
75+
font-size: 0.875rem;
76+
color: var(--colour-ti-base);
77+
}
78+
}
79+
}
80+
}
81+
</style>

frontend/src/views/BookerView/index.vue

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -127,43 +127,41 @@ export default {
127127
</script>
128128

129129
<template>
130-
<div>
131-
<!-- booking page content: loading -->
132-
<main
133-
v-if="activeView === BookingCalendarView.Loading"
134-
class="booking-loading-container"
135-
>
136-
<loading-spinner/>
137-
</main>
138-
<!-- booking page content: invalid link -->
139-
<main
140-
v-else-if="activeView === BookingCalendarView.Invalid"
141-
class="booking-invalid-container"
142-
>
143-
<booking-view-error
144-
:heading="errorHeading"
145-
:body="errorBody"
146-
/>
147-
</main>
148-
<!-- booking page content: successful booking -->
149-
<main
150-
v-else-if="activeView === BookingCalendarView.Success"
151-
class="booking-success-container"
152-
>
153-
<booking-view-success
154-
:attendee-email="attendee.email"
155-
:selected-event="selectedEvent"
156-
:requested="appointment?.booking_confirmation"
157-
/>
158-
</main>
159-
<!-- booking page content: time slot selection -->
160-
<main
161-
v-else
162-
class="booking-slot-selection-container"
163-
>
164-
<booking-view-slot-selection />
165-
</main>
166-
</div>
130+
<!-- booking page content: loading -->
131+
<main
132+
v-if="activeView === BookingCalendarView.Loading"
133+
class="booking-loading-container"
134+
>
135+
<loading-spinner/>
136+
</main>
137+
<!-- booking page content: invalid link -->
138+
<main
139+
v-else-if="activeView === BookingCalendarView.Invalid"
140+
class="booking-invalid-container"
141+
>
142+
<booking-view-error
143+
:heading="errorHeading"
144+
:body="errorBody"
145+
/>
146+
</main>
147+
<!-- booking page content: successful booking -->
148+
<main
149+
v-else-if="activeView === BookingCalendarView.Success"
150+
class="booking-success-container"
151+
>
152+
<booking-view-success
153+
:attendee-email="attendee.email"
154+
:selected-event="selectedEvent"
155+
:requested="appointment?.booking_confirmation"
156+
/>
157+
</main>
158+
<!-- booking page content: time slot selection -->
159+
<main
160+
v-else
161+
class="booking-slot-selection-container"
162+
>
163+
<booking-view-slot-selection />
164+
</main>
167165
</template>
168166

169167
<style scoped>
@@ -211,4 +209,10 @@ export default {
211209
flex-direction: row;
212210
}
213211
}
212+
213+
@media (--lg) {
214+
.booking-slot-selection-container {
215+
padding-inline: 3.5rem;
216+
}
217+
}
214218
</style>

0 commit comments

Comments
 (0)