Skip to content

Commit 0d567d4

Browse files
committed
各種右上のボタンを設定
1 parent 7f74203 commit 0d567d4

File tree

7 files changed

+594
-7
lines changed

7 files changed

+594
-7
lines changed

src/components/ActionButton.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
@click="$emit('click')"
88
>
99
<span>{{ text }}</span>
10+
<v-icon v-if="logoutIcon">mdi-login-variant</v-icon>
1011
</v-btn>
1112
</template>
1213

@@ -28,6 +29,9 @@ export default class ActionButton extends Vue {
2829
2930
@Prop({ default: false })
3031
isLoading?: boolean
32+
33+
@Prop({ default: false })
34+
logoutIcon?: boolean
3135
}
3236
</script>
3337

src/components/BaseDialog.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
<template>
2-
<v-dialog :value="value" :persistent="modal" @input="$emit('input', $event)">
2+
<v-dialog
3+
max-width="320px"
4+
:value="value"
5+
:persistent="modal"
6+
@input="$emit('input', $event)"
7+
>
38
<v-card class="DialogCard">
49
<v-card-title class="DialogCardTitle">
510
<v-icon class="DialogCardTitleIcon" size="48">{{ iconName }}</v-icon>

src/components/ViewerDialog.vue

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<template>
2+
<v-dialog
3+
max-width="320px"
4+
:value="value"
5+
:persistent="modal"
6+
@input="$emit('input', $event)"
7+
>
8+
<v-card class="DialogCard">
9+
<v-card-title class="DialogCardTitle">
10+
<v-icon class="DialogCardTitleIcon" size="48">{{ iconName }}</v-icon>
11+
<slot class="DialogCardTitleText" name="title" />
12+
</v-card-title>
13+
<v-container class="DialogCardContentContainer">
14+
<slot />
15+
</v-container>
16+
<v-card-actions class="DialogCardButtons px-4">
17+
<action-button
18+
v-for="(action, i) in actions"
19+
:key="i"
20+
class="my-3"
21+
:text="action.buttonLabel"
22+
@click="doDialogAction(i)"
23+
/>
24+
<action-button
25+
v-if="!hideDefaultCancelButton"
26+
:logout-icon="true"
27+
:text="defaultCancelButtonLabel"
28+
theme="border"
29+
class="my-3"
30+
@click="clickLogoutButton"
31+
/>
32+
</v-card-actions>
33+
</v-card>
34+
</v-dialog>
35+
</template>
36+
37+
<script lang="ts">
38+
import Vue from 'vue'
39+
import ActionButton from '@/components/ActionButton.vue'
40+
41+
export type DialogAction = {
42+
buttonLabel: string
43+
/**
44+
* ボタン押下時に実行する処理。実行後に BaseModalDialog を閉じないようにするには true を返す。
45+
*/
46+
action: () => boolean | void
47+
}
48+
49+
type Props = {
50+
iconName: string
51+
hideDefaultCancelButton: boolean
52+
defaultCancelButtonLabel: string
53+
actions: DialogAction[]
54+
modal: boolean
55+
value: boolean
56+
}
57+
58+
type Methods = {
59+
doDialogAction(buttonIndex: number): void
60+
clickLogoutButton(): void
61+
}
62+
63+
export default Vue.extend<unknown, Methods, unknown, Props>({
64+
name: 'ViewerDialog',
65+
components: { ActionButton },
66+
props: {
67+
iconName: {
68+
type: String,
69+
required: true
70+
},
71+
hideDefaultCancelButton: {
72+
type: Boolean,
73+
required: false,
74+
default: false
75+
},
76+
defaultCancelButtonLabel: {
77+
type: String,
78+
required: false,
79+
default: 'キャンセル'
80+
},
81+
actions: {
82+
type: Array as () => DialogAction[],
83+
required: true
84+
},
85+
modal: {
86+
type: Boolean,
87+
required: false,
88+
default: false
89+
},
90+
value: {
91+
type: Boolean,
92+
default: false
93+
}
94+
},
95+
methods: {
96+
doDialogAction(index) {
97+
if (!this.actions[index].action()) {
98+
this.$emit('input', false)
99+
}
100+
},
101+
clickLogoutButton() {
102+
this.$emit('input', false)
103+
this.$emit('clickLogout')
104+
}
105+
}
106+
})
107+
</script>
108+
109+
<style lang="scss" scoped>
110+
.v-dialog {
111+
.DialogCard {
112+
border-radius: 14px;
113+
114+
&Title,
115+
&Buttons {
116+
flex-direction: column;
117+
}
118+
119+
&Title,
120+
&TitleIcon {
121+
color: $color-base-color-01;
122+
font-size: 16px;
123+
}
124+
}
125+
}
126+
</style>

src/layouts/classes.vue

Lines changed: 117 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
<template>
22
<v-app>
3+
<v-dialog v-model="openCalenderDialog" max-width="320px">
4+
<v-date-picker
5+
v-model="date"
6+
locale="ja"
7+
first-day-of-week="1"
8+
@input="openCalenderDialog = false"
9+
/>
10+
</v-dialog>
11+
<viewer-dialog
12+
v-model="openClassIdDialog"
13+
icon-name="mdi-clipboard-account"
14+
default-cancel-button-label="ログアウト"
15+
:logout-icon="true"
16+
:actions="[
17+
{
18+
buttonLabel: '閉じる',
19+
action: () => {
20+
return false
21+
}
22+
}
23+
]"
24+
@clickLogout="clickLogout"
25+
>
26+
<template v-slot:title>
27+
今、ログインしているクラスです
28+
</template>
29+
<template v-slot:default>
30+
<div class="ClassIdModal-Contents">
31+
<p class="ClassIdModal-ClassText">{{ className }}</p>
32+
<p class="ClassIdModal-Text">クラスID</p>
33+
<div class="ClassIdModal-Id">{{ classId }}</div>
34+
</div>
35+
</template>
36+
</viewer-dialog>
337
<v-overlay :value="loading" color="#0071C2" opacity="1" z-index="9999">
438
<div class="loader">
539
Loading
@@ -8,9 +42,28 @@
842
<v-app-bar fixed app class="bar" elevation="0">
943
<HeaderLogo />
1044
<v-spacer />
11-
<v-btn fab small outlined rounded color="#0071C2">
12-
<v-icon>mdi-clipboard-account</v-icon>
13-
</v-btn>
45+
<div class="classes-buttons">
46+
<v-btn
47+
fab
48+
small
49+
outlined
50+
rounded
51+
color="#0071C2"
52+
@click="openCalenderDialog = true"
53+
>
54+
<v-icon>mdi-calendar-today</v-icon>
55+
</v-btn>
56+
<v-btn
57+
fab
58+
small
59+
outlined
60+
rounded
61+
color="#0071C2"
62+
@click="openClassIdDialog = true"
63+
>
64+
<v-icon>mdi-clipboard-account</v-icon>
65+
</v-btn>
66+
</div>
1467
<template v-slot:extension>
1568
<div class="header-calender">
1669
<CalendarBar v-model="app.currentDate" />
@@ -27,29 +80,57 @@
2780

2881
<script lang="ts">
2982
import Vue from 'vue'
83+
import dayjs from 'dayjs'
3084
import HeaderLogo from '@/assets/svgs/header_logo.svg'
3185
import CalendarBar from '@/components/CalendarBar.vue'
86+
import ViewerDialog from '@/components/ViewerDialog.vue'
3287
import { vxm } from '@/store'
3388
3489
type LocalData = {
3590
loading: boolean
91+
openCalenderDialog: boolean
92+
openClassIdDialog: boolean
93+
classId: string
94+
className: string
3695
app: typeof vxm.app
3796
}
3897
3998
export default Vue.extend({
4099
middleware: 'checkClassData',
41100
components: {
42101
CalendarBar,
102+
ViewerDialog,
43103
HeaderLogo
44104
},
45105
data(): LocalData {
46106
return {
47107
loading: true,
108+
openCalenderDialog: false,
109+
openClassIdDialog: false,
110+
classId: vxm.classData.classId,
111+
className: vxm.classData.className,
48112
app: vxm.app
49113
}
50114
},
115+
computed: {
116+
date: {
117+
get() {
118+
return dayjs(vxm.app.currentDate).format('YYYY-MM-DD')
119+
},
120+
set(newValue: string) {
121+
vxm.app.setDate(dayjs(newValue).toDate())
122+
}
123+
}
124+
},
51125
mounted(): void {
52126
this.loading = false
127+
},
128+
methods: {
129+
clickLogout() {
130+
vxm.classData.unLoadClassData().then(() => {
131+
this.$router.push('/')
132+
})
133+
}
53134
}
54135
})
55136
</script>
@@ -86,4 +167,37 @@ export default Vue.extend({
86167
.classes-container {
87168
height: 100%;
88169
}
170+
.classes-buttons {
171+
padding: 0 4px;
172+
}
173+
.ClassIdModal-Contents {
174+
display: flex;
175+
flex-direction: column;
176+
justify-content: center;
177+
align-items: center;
178+
padding: 0;
179+
}
180+
.ClassIdModal-Text {
181+
font-size: 16px;
182+
font-weight: bold;
183+
color: $color-gray;
184+
margin: 6px 0 12px;
185+
}
186+
.ClassIdModal-ClassText {
187+
font-size: 16px;
188+
color: $color-gray;
189+
margin: 6px 0 12px;
190+
}
191+
.ClassIdModal-Id {
192+
max-width: 9em;
193+
padding: 16px 24px;
194+
text-align: center;
195+
background-color: $color-back-gray;
196+
border: 2px solid $color-base-color-01;
197+
border-radius: 14px;
198+
letter-spacing: 0.2em;
199+
line-height: 1.25;
200+
font-size: 30px;
201+
color: $color-gray;
202+
}
89203
</style>

0 commit comments

Comments
 (0)