Skip to content

Commit 3783302

Browse files
committed
vue
1 parent 7e7452a commit 3783302

File tree

5 files changed

+235
-207
lines changed

5 files changed

+235
-207
lines changed

Vue/src/assets/main.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
-moz-osx-font-smoothing: grayscale;
55
color: #2c3e50;
66
margin: 50px 50px;
7-
width: 90vh;
7+
width: 90vw;
88
}

Vue/src/components/HomeContent.vue

Lines changed: 186 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,195 @@
11
<script setup lang="ts">
2-
import { computed, ref } from 'vue';
2+
import { ref, type Ref } from 'vue';
33
44
import 'devextreme/dist/css/dx.material.blue.light.compact.css';
5-
import DxButton from 'devextreme-vue/button';
6-
7-
const props = defineProps({
8-
text: {
9-
type: String,
10-
default: 'count',
11-
},
12-
});
13-
const count = ref(0);
14-
const buttonText = computed<string>(
15-
() => `Click ${props.text}: ${count.value}`
16-
);
17-
function clickHandler() {
18-
count.value += 1;
5+
import { DxEditing, DxScheduler, type DxSchedulerTypes } from 'devextreme-vue/scheduler';
6+
import type { DxButtonTypes } from 'devextreme-vue/button';
7+
import DxPopup, { DxToolbarItem } from 'devextreme-vue/popup';
8+
import { DxScrollView } from 'devextreme-vue/scroll-view';
9+
import { DxSelectBox } from 'devextreme-vue/select-box';
10+
import { formatDate } from 'devextreme/localization';
11+
import notify from 'devextreme/ui/notify';
12+
13+
import { appointments, EditData, rows, seats } from './data.js';
14+
15+
const views: DxSchedulerTypes.ViewType[] = ['day', 'timelineDay'];
16+
17+
const currentDate: Date = new Date(2015, 4, 25);
18+
19+
const schedulerRef: Ref<DxScheduler | null> = ref(null);
20+
21+
const editAppointmentData: Ref<EditData> = ref(new EditData());
22+
23+
const isCustomPopupVisible = ref(false);
24+
25+
function onAppointmentFormOpening(e: DxSchedulerTypes.AppointmentFormOpeningEvent) {
26+
e.cancel = true;
27+
editAppointmentData.value = { ...e.appointmentData as EditData };
28+
if (editAppointmentData.value.id) {
29+
isCustomPopupVisible.value = true;
30+
}
31+
}
32+
33+
function onHiding() {
34+
editAppointmentData.value = new EditData();
1935
}
36+
37+
function setSeatPrice(basePrice: number, row: string): number {
38+
const multiplier: Record<string, number> = {
39+
A: 1,
40+
B: 2,
41+
C: 3,
42+
D: 4,
43+
};
44+
return basePrice * multiplier[row];
45+
}
46+
47+
function updateBooking() {
48+
if (editAppointmentData.value.seatRow && editAppointmentData.value.seatNumber) {
49+
const oldAppointmentData = appointments.find(item => item.id === editAppointmentData.value.id);
50+
if (schedulerRef.value?.instance && oldAppointmentData) {
51+
schedulerRef.value.instance.updateAppointment(
52+
oldAppointmentData,
53+
editAppointmentData.value
54+
);
55+
notify(`Selected seat ${editAppointmentData.value.seatRow}${editAppointmentData.value.seatNumber} for ${editAppointmentData.value.text}. Enjoy!`);
56+
}
57+
}
58+
isCustomPopupVisible.value = false;
59+
}
60+
61+
const buttonOptions: DxButtonTypes.Properties = {
62+
text: 'OK',
63+
onClick: updateBooking,
64+
};
65+
2066
</script>
2167
<template>
2268
<div>
23-
<DxButton
24-
:text="buttonText"
25-
@click="clickHandler"
26-
/>
69+
<div class="long-title">
70+
<h3>DXCinema Upcoming Movies</h3>
71+
</div>
72+
73+
<DxScheduler
74+
id="scheduler"
75+
ref="schedulerRef"
76+
:data-source="appointments"
77+
:views="views"
78+
current-view="day"
79+
:current-date="currentDate"
80+
:first-day-of-week="0"
81+
:start-day-hour="9"
82+
:end-day-hour="23"
83+
:show-all-day-panel="false"
84+
:height="600"
85+
@appointment-form-opening="onAppointmentFormOpening"
86+
>
87+
<DxEditing
88+
:allow-resizing="false"
89+
:allow-dragging="false"
90+
/>
91+
</DxScheduler>
92+
93+
<DxPopup
94+
:width="500"
95+
:height="520"
96+
:hide-on-outside-click="true"
97+
v-model:visible="isCustomPopupVisible"
98+
:title="editAppointmentData.text"
99+
@hiding="onHiding"
100+
>
101+
<template #content>
102+
<DxScrollView
103+
width="90%"
104+
height="90%"
105+
>
106+
<div class="movie-popup-content">
107+
<img :src="editAppointmentData.image">
108+
<div class="movie-details">
109+
<div>
110+
<p class="movie-title">{{ editAppointmentData.text }}</p>
111+
<p>Year: {{ editAppointmentData.year }}</p>
112+
<p>Duration: {{ editAppointmentData.duration }} minutes</p>
113+
</div>
114+
<div class="movie-time">
115+
{{ formatDate(editAppointmentData.startDate, "shortTime") }} -
116+
{{ formatDate(editAppointmentData.endDate, "shortTime") }}
117+
</div>
118+
<p>Price ($):
119+
<span>
120+
{{
121+
editAppointmentData.seatRow && editAppointmentData.seatNumber
122+
? setSeatPrice(
123+
editAppointmentData.price,
124+
editAppointmentData.seatRow
125+
)
126+
: "Pick a seat for pricing"
127+
}}
128+
</span>
129+
</p>
130+
<DxSelectBox
131+
:data-source="rows"
132+
:width="400"
133+
placeholder="Pick a row"
134+
v-model:value="editAppointmentData.seatRow"
135+
/>
136+
<DxSelectBox
137+
:data-source="seats"
138+
:width="400"
139+
placeholder="Pick a seat"
140+
v-model:value="editAppointmentData.seatNumber"
141+
/>
142+
</div>
143+
</div>
144+
</DxScrollView>
145+
</template>
146+
<DxToolbarItem
147+
widget="dxButton"
148+
toolbar="bottom"
149+
location="after"
150+
:options="buttonOptions"
151+
/>
152+
</DxPopup>
27153
</div>
28154
</template>
155+
156+
<style scoped>
157+
.long-title h3 {
158+
font-family: 'Segoe UI Light', 'Helvetica Neue Light', 'Segoe UI', 'Helvetica Neue', 'Trebuchet MS', Verdana;
159+
font-weight: 200;
160+
font-size: 28px;
161+
text-align: center;
162+
margin-bottom: 20px;
163+
}
164+
165+
.movie-popup-content {
166+
display: flex;
167+
flex-direction: row;
168+
gap: 30px;
169+
}
170+
171+
.movie-popup-content img {
172+
height: auto;
173+
width: 200px;
174+
flex: 0 0 auto;
175+
max-width: 100%;
176+
}
177+
178+
.movie-title {
179+
font-family: 'Segoe UI Light', 'Helvetica Neue Light', 'Segoe UI', 'Helvetica Neue', 'Trebuchet MS', Verdana;
180+
font-size: 24px;
181+
text-align: center;
182+
}
183+
184+
.movie-details {
185+
display: flex;
186+
flex-direction: column;
187+
width: 200px;
188+
gap: 10px;
189+
}
190+
191+
.movie-time {
192+
font-size: 18px;
193+
text-align: center;
194+
}
195+
</style>

Vue/src/components/orig_data.js renamed to Vue/src/components/data.ts

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,48 @@
1-
export const data = [
1+
export interface Data {
2+
id: number;
3+
4+
price: number;
5+
6+
startDate: Date;
7+
8+
endDate: Date;
9+
10+
text: string;
11+
12+
director: string;
13+
14+
year: number;
15+
16+
image: string;
17+
18+
duration: number;
19+
}
20+
21+
export class EditData implements Data {
22+
id = 0;
23+
24+
price = 0;
25+
26+
startDate: Date = new Date();
27+
28+
endDate: Date = new Date();
29+
30+
text = '';
31+
32+
director = '';
33+
34+
year = 1900;
35+
36+
image = '';
37+
38+
duration = 0;
39+
40+
seatRow = '';
41+
42+
seatNumber = 0;
43+
}
44+
45+
export const appointments: Data[] = [
246
{
347
id: 1,
448
price: 10,
@@ -37,6 +81,6 @@ export const data = [
3781
},
3882
];
3983

40-
export const rows = ['A', 'B', 'C', 'D'];
84+
export const rows: string[] = ['A', 'B', 'C', 'D'];
4185

42-
export const seats = [1, 2, 3, 4, 5];
86+
export const seats: number[] = [1, 2, 3, 4, 5];

0 commit comments

Comments
 (0)