first commit after refactor to vite
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
3
.vscode/extensions.json
vendored
Normal file
3
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["johnsoncodehk.volar"]
|
||||
}
|
||||
11
README.md
Normal file
11
README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Vue 3 + Typescript + Vite
|
||||
|
||||
This template should help get you started developing with Vue 3 and Typescript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
- [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)
|
||||
|
||||
## Type Support For `.vue` Imports in TS
|
||||
|
||||
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's `.vue` type support plugin by running `Volar: Switch TS Plugin on/off` from VSCode command palette.
|
||||
13
index.html
Normal file
13
index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
2774
package-lock.json
generated
Normal file
2774
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
23
package.json
Normal file
23
package.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "duty-schedule-fe",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc --noEmit && vite build",
|
||||
"serve": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.10.2",
|
||||
"bootstrap": "^5.1.1",
|
||||
"date-fns": "^2.24.0",
|
||||
"vue": "^3.2.16",
|
||||
"vue-month-picker": "^1.5.0",
|
||||
"vue-router": "^4.0.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^1.9.2",
|
||||
"typescript": "^4.4.3",
|
||||
"vite": "^2.6.0",
|
||||
"vue-tsc": "^0.3.0"
|
||||
}
|
||||
}
|
||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
27
src/App.vue
Normal file
27
src/App.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<script setup lang="ts">
|
||||
// This starter template is using Vue 3 <script setup> SFCs
|
||||
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
|
||||
import HelloWorld from './components/HelloWorld.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<img alt="Vue logo" src="./assets/logo.png" />
|
||||
<v-app>
|
||||
<v-main>
|
||||
<div class="container">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</v-main>
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
margin-top: 60px;
|
||||
}
|
||||
</style>
|
||||
BIN
src/assets/logo.png
Normal file
BIN
src/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
52
src/components/HelloWorld.vue
Normal file
52
src/components/HelloWorld.vue
Normal file
@@ -0,0 +1,52 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
defineProps<{ msg: string }>()
|
||||
|
||||
const count = ref(0)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ msg }}</h1>
|
||||
|
||||
<p>
|
||||
Recommended IDE setup:
|
||||
<a href="https://code.visualstudio.com/" target="_blank">VSCode</a>
|
||||
+
|
||||
<a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
|
||||
</p>
|
||||
|
||||
<p>See <code>README.md</code> for more information.</p>
|
||||
|
||||
<p>
|
||||
<a href="https://vitejs.dev/guide/features.html" target="_blank">
|
||||
Vite Docs
|
||||
</a>
|
||||
|
|
||||
<a href="https://v3.vuejs.org/" target="_blank">Vue 3 Docs</a>
|
||||
</p>
|
||||
|
||||
<button type="button" @click="count++">count is: {{ count }}</button>
|
||||
<p>
|
||||
Edit
|
||||
<code>components/HelloWorld.vue</code> to test hot module replacement.
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
|
||||
label {
|
||||
margin: 0 0.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #eee;
|
||||
padding: 2px 4px;
|
||||
border-radius: 4px;
|
||||
color: #304455;
|
||||
}
|
||||
</style>
|
||||
105
src/components/MonthPicker.vue
Normal file
105
src/components/MonthPicker.vue
Normal file
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<div class="d-flex justify-content-center" >
|
||||
<button type="button" class="btn btn-outline-primary" @click="openPicker" v-show="state === 'closed'">
|
||||
{{months[selectedMonth]}} {{selectedYear}}
|
||||
</button>
|
||||
|
||||
<table v-show="state === 'month'" class="table table-bordered table-sm">
|
||||
<tbody>
|
||||
<tr v-for="n in 3">
|
||||
<td v-for="m in 4" @click="updateMonth(m+4*n-5)" :class="{selected: selectedMonth===(m+4*n-5)}">
|
||||
{{months[m+4*n-5]}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table v-show="state === 'year'" class="table table-bordered table-sm">
|
||||
<tbody>
|
||||
<tr v-for="n in 3">
|
||||
<td v-for="m in 3" @click="updateYear(years[m+3*n-4])" :class="{selected: selectedYear === years[m+3*n-4]}">
|
||||
{{years[m+3*n-4]}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, Ref, ComputedRef } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
selectedMonth: number,
|
||||
selectedYear: number,
|
||||
state: ('closed'|'year'|'month')
|
||||
}>()
|
||||
|
||||
const selectedMonth : Ref<number>= ref(props.selectedMonth)
|
||||
const selectedYear : Ref<number> = ref(props.selectedYear)
|
||||
const state : Ref<'closed'|'year'|'month'> = ref(props.state)
|
||||
|
||||
const months : string[] = [
|
||||
'Jan', 'Feb', 'Mrz', 'Apr',
|
||||
'Mai', 'Jun', 'Jul', 'Aug',
|
||||
'Sept', 'Okt', 'Nov', 'Dez'
|
||||
]
|
||||
|
||||
/**
|
||||
* -4 -3 -2
|
||||
* -1 0 +1
|
||||
* +2 +3 +4
|
||||
*/
|
||||
|
||||
const years : ComputedRef<number[]> = computed(() => {
|
||||
let arr : number[] = []
|
||||
for (let i = 0; i < 9; i++) {
|
||||
arr.push(selectedYear.value - 4 + i)
|
||||
}
|
||||
return arr
|
||||
})
|
||||
|
||||
function updateMonth(monthId : number) {
|
||||
selectedMonth.value = monthId
|
||||
state.value = 'closed'
|
||||
|
||||
}
|
||||
|
||||
function updateYear(year : number) {
|
||||
selectedYear.value = year
|
||||
state.value = 'month'
|
||||
}
|
||||
|
||||
function openPicker() {
|
||||
state.value = 'year'
|
||||
}
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'getYear', year: number): number
|
||||
(e: 'getMonth', month: number): number
|
||||
}>()
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
table {
|
||||
width: 250px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
td, tr {
|
||||
border: 1px solid #0d6efd ;
|
||||
border-collapse: collapse;
|
||||
color: #0D6EFD
|
||||
}
|
||||
td:hover {
|
||||
background-color: #0D6EFD;
|
||||
color: #fff;
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
.selected {
|
||||
background-color: #0D6EFD;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
84
src/components/Schedule.vue
Normal file
84
src/components/Schedule.vue
Normal file
@@ -0,0 +1,84 @@
|
||||
<template lang="pug">
|
||||
|
||||
h1(v-if="isValid(startDate)") {{format(startDate, "MMMM y", {locale: de})}}
|
||||
|
||||
table(class='table' v-for="(row, rIndex) in dates" :key="rIndex")
|
||||
thead
|
||||
tr
|
||||
td(v-for="(day, index) in weekdays" :key="index") {{ day }}
|
||||
tr
|
||||
td(v-for="(date, dIndex) in row" :key="dIndex")
|
||||
template(v-if="date !== null") {{ format(date, "dd.MM.")}}
|
||||
tbody
|
||||
tr
|
||||
td(v-for="(date, dIndex) in row" :key="dIndex")
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { toRef, computed } from 'vue'
|
||||
import { addMonths, subDays, addDays, format, getISODay, isValid, eachDayOfInterval } from 'date-fns'
|
||||
import { de } from 'date-fns/locale'
|
||||
|
||||
/*
|
||||
* Props / Refs
|
||||
*/
|
||||
const props = defineProps<{
|
||||
startDate: Date,
|
||||
initialOffset: number
|
||||
}>()
|
||||
|
||||
const startDate = toRef(props, 'startDate')
|
||||
const endDate = computed(():Date => subDays(addMonths(startDate.value, 1), 1))
|
||||
|
||||
/*
|
||||
* Local variables
|
||||
*/
|
||||
const weekdays : string[] = doubleWeekdays()
|
||||
const employees : string[] = ['Pascal', 'Karin', 'Sandra']
|
||||
|
||||
const daysInMonth : Date[] = eachDayOfInterval({
|
||||
start: startDate.value,
|
||||
end: endDate.value
|
||||
})
|
||||
const offset : number = getISODay(startDate.value) - 1 + props.initialOffset
|
||||
|
||||
|
||||
const dates = computed( () => {
|
||||
let arr = []
|
||||
let row = []
|
||||
let start = startDate.value
|
||||
let end = endDate.value
|
||||
let i
|
||||
|
||||
for (i = 0; i < offset ; i++) {
|
||||
row.push(null)
|
||||
}
|
||||
|
||||
while (start <= end){
|
||||
while (i < 14 && start <= end){
|
||||
row.push(start)
|
||||
start = addDays(start, 1)
|
||||
i++
|
||||
}
|
||||
arr.push(row)
|
||||
row = []
|
||||
i = 0
|
||||
}
|
||||
|
||||
return arr
|
||||
})
|
||||
|
||||
function doubleWeekdays() : string[] {
|
||||
let arr = ['Mo.', 'Di.', 'Mi.', 'Do.', 'Fr.', 'Sa.', 'So.']
|
||||
return arr.concat(arr)
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
table {
|
||||
table-layout: fixed
|
||||
}
|
||||
</style>
|
||||
8
src/env.d.ts
vendored
Normal file
8
src/env.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.vue' {
|
||||
import { DefineComponent } from 'vue'
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
9
src/main.ts
Normal file
9
src/main.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import "bootstrap"
|
||||
import "bootstrap/dist/css/bootstrap.min.css"
|
||||
|
||||
createApp(App)
|
||||
.use(router)
|
||||
.mount('#app')
|
||||
17
src/router/index.ts
Normal file
17
src/router/index.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
|
||||
import Home from '../views/Home.vue'
|
||||
|
||||
const routes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'Home',
|
||||
component: Home
|
||||
}
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes
|
||||
})
|
||||
|
||||
export default router
|
||||
40
src/views/Home.vue
Normal file
40
src/views/Home.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template lang="pug">
|
||||
|
||||
p SelectedMonth: {{selectedMonth}}, SelectedYear: {{selectedYear}}
|
||||
|
||||
MonthPicker(:selectedMonth="selectedMonth" :selectedYear="selectedYear" state="closed")
|
||||
|
||||
div(class="mt-5" v-for="(month, index) in months" :key="index")
|
||||
Schedule( :startDate="month" :initialOffset="iOffsets[index]")
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { getYear, getMonth, eachMonthOfInterval, getDaysInMonth, getISODay } from 'date-fns'
|
||||
import Schedule from '/src/components/Schedule.vue'
|
||||
import MonthPicker from '/src/components/MonthPicker.vue'
|
||||
|
||||
const selectedMonth = ref(getMonth(new Date()))
|
||||
const selectedYear = ref(getYear(new Date()))
|
||||
|
||||
const months = computed(() => {
|
||||
return eachMonthOfInterval({
|
||||
start: new Date(selectedYear.value, selectedMonth.value - 1),
|
||||
end : new Date(selectedYear.value, selectedMonth.value + 1)
|
||||
})
|
||||
})
|
||||
|
||||
const iOffsets = computed(() => {
|
||||
let arr : number[] = []
|
||||
arr.push(0)
|
||||
|
||||
months.value.forEach(month => {
|
||||
if ( getDaysInMonth(month) + getISODay(month) - 1 + arr[arr.length - 1] > 34) {
|
||||
arr.push(7)
|
||||
}
|
||||
else arr.push(0)
|
||||
})
|
||||
return arr
|
||||
})
|
||||
</script>
|
||||
15
tsconfig.json
Normal file
15
tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
"sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": ["esnext", "dom"]
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
|
||||
}
|
||||
7
vite.config.ts
Normal file
7
vite.config.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()]
|
||||
})
|
||||
Reference in New Issue
Block a user