@dargmuesli/nuxt-vio 2.0.1 → 3.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app.config.ts +83 -40
- package/components/vio/_/VioApp.vue +92 -0
- package/components/{VioError.vue → vio/_/VioError.vue} +1 -1
- package/components/{VioLink.vue → vio/_/VioLink.vue} +2 -2
- package/components/vio/button/VioButtonColored.vue +52 -0
- package/components/vio/card/VioCard.vue +19 -0
- package/components/vio/card/state/VioCardState.vue +20 -0
- package/components/vio/card/state/VioCardStateAlert.vue +14 -0
- package/components/vio/form/VioForm.vue +84 -0
- package/components/vio/form/VioFormCheckbox.vue +27 -0
- package/components/vio/form/input/VioFormInput.vue +192 -0
- package/components/vio/form/input/VioFormInputIconWrapper.vue +7 -0
- package/components/vio/form/input/VioFormInputUrl.vue +54 -0
- package/components/vio/form/input/state/VioFormInputState.vue +5 -0
- package/components/vio/form/input/state/VioFormInputStateError.vue +32 -0
- package/components/vio/form/input/state/VioFormInputStateInfo.vue +32 -0
- package/components/vio/icon/IconArrowRight.vue +31 -0
- package/components/vio/icon/IconCalendar.vue +31 -0
- package/components/vio/icon/IconChatOutline.vue +27 -0
- package/components/vio/icon/IconChatSolid.vue +26 -0
- package/components/vio/icon/IconCheckCircle.vue +29 -0
- package/components/vio/icon/IconContainer.vue +15 -0
- package/components/vio/icon/IconDownload.vue +31 -0
- package/components/vio/icon/IconExclamationCircle.vue +29 -0
- package/components/vio/icon/IconHome.vue +31 -0
- package/components/vio/icon/IconHourglass.vue +32 -0
- package/components/vio/icon/IconLightbulb.vue +27 -0
- package/components/vio/icon/IconLogo.vue +17 -0
- package/components/vio/icon/IconMixcloud.vue +23 -0
- package/components/vio/icon/IconMusic.vue +27 -0
- package/components/vio/icon/IconPlay.vue +25 -0
- package/components/vio/icon/IconShare.vue +27 -0
- package/components/{VioLayout.vue → vio/layout/VioLayout.vue} +1 -1
- package/components/vio/layout/VioLayoutBreadcrumbs.vue +83 -0
- package/components/vio/layout/VioLayoutFooter.vue +40 -0
- package/components/vio/layout/VioLayoutFooterCategory.vue +17 -0
- package/components/vio/layout/VioLayoutHeader.vue +98 -0
- package/components/vio/layout/VioLayoutSpanList.vue +20 -0
- package/components/vio/loader/indicator/VioLoaderIndicator.vue +14 -0
- package/components/vio/loader/indicator/VioLoaderIndicatorPing.vue +12 -0
- package/components/vio/loader/indicator/VioLoaderIndicatorSpinner.vue +24 -0
- package/components/{VioLegalNotice.vue → vio/page/VioPageLegalNotice.vue} +10 -8
- package/components/{VioPrivacyPolicy.vue → vio/page/VioPagePrivacyPolicy.vue} +19 -12
- package/composables/useAppLayout.ts +12 -18
- package/composables/useDateTime.ts +17 -0
- package/composables/useFavicons.ts +5 -33
- package/composables/useFireError.ts +17 -0
- package/composables/useGetServiceHref.ts +21 -0
- package/composables/useHeadDefault.ts +21 -0
- package/composables/usePolyfills.ts +23 -0
- package/composables/useStrapiFetch.ts +10 -0
- package/error.vue +5 -2
- package/locales/de.json +7 -1
- package/locales/en.json +7 -1
- package/nuxt.config.ts +56 -10
- package/package.json +37 -25
- package/pages/legal-notice.vue +1 -1
- package/pages/privacy-policy.vue +1 -1
- package/plugins/dayjs.ts +34 -0
- package/plugins/gtag.client.ts +3 -0
- package/plugins/i18n.ts +5 -0
- package/plugins/marked.ts +9 -0
- package/server/middleware/headers.ts +41 -10
- package/server/tsconfig.json +1 -1
- package/server/utils/util.ts +2 -0
- package/store/auth.ts +32 -0
- package/tailwind.config.ts +131 -10
- package/types/api.d.ts +9 -0
- package/types/fetch.d.ts +8 -0
- package/types/modules/gql.d.ts +6 -0
- package/types/modules/graphql.d.ts +6 -0
- package/utils/constants.ts +10 -1
- package/utils/form.ts +19 -0
- package/utils/networking.ts +117 -0
- package/utils/text.ts +20 -0
- package/LICENSE +0 -674
- package/components/VioApp.vue +0 -59
- /package/components/{VioButton.vue → vio/button/VioButton.vue} +0 -0
- /package/components/{VioHr.vue → vio/layout/VioLayoutHr.vue} +0 -0
package/nuxt.config.ts
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
import { dirname, join } from 'node:path'
|
2
2
|
import { fileURLToPath } from 'node:url'
|
3
3
|
|
4
|
-
import {
|
4
|
+
import {
|
5
|
+
I18N_COOKIE_NAME,
|
6
|
+
I18N_MODULE_CONFIG,
|
7
|
+
TIMEZONE_COOKIE_NAME,
|
8
|
+
SITE_NAME,
|
9
|
+
} from './utils/constants'
|
5
10
|
|
6
11
|
const currentDir = dirname(fileURLToPath(import.meta.url))
|
7
12
|
|
8
13
|
const BASE_URL =
|
9
|
-
'https
|
14
|
+
(process.env.NUXT_PUBLIC_STACK_DOMAIN ? 'https' : 'http') +
|
15
|
+
'://' +
|
10
16
|
(process.env.NUXT_PUBLIC_STACK_DOMAIN ||
|
11
17
|
`${process.env.HOST || 'localhost'}:${
|
12
18
|
!process.env.NODE_ENV || process.env.NODE_ENV === 'development'
|
@@ -17,22 +23,35 @@ const BASE_URL =
|
|
17
23
|
// https://v3.nuxtjs.org/api/configuration/nuxt.config
|
18
24
|
export default defineNuxtConfig({
|
19
25
|
alias: {
|
20
|
-
|
21
|
-
|
26
|
+
dayjs: 'dayjs',
|
27
|
+
sweetalert2: 'sweetalert2',
|
28
|
+
}, // TODO: remove (https://github.com/nuxt/nuxt/issues/19426)
|
22
29
|
app: {
|
23
30
|
head: {
|
24
31
|
htmlAttrs: {
|
25
32
|
lang: 'en', // fallback data to prevent invalid html at generation
|
26
33
|
},
|
27
|
-
titleTemplate: `%s`,
|
28
34
|
title: SITE_NAME, // fallback data to prevent invalid html at generation
|
35
|
+
titleTemplate: '%s', // fully set in `composables/useAppLayout.ts`
|
36
|
+
},
|
37
|
+
pageTransition: {
|
38
|
+
name: 'layout',
|
39
|
+
},
|
40
|
+
},
|
41
|
+
devtools: {
|
42
|
+
enabled: process.env.NODE_ENV !== 'production',
|
43
|
+
timeline: {
|
44
|
+
enabled: true,
|
29
45
|
},
|
30
46
|
},
|
31
47
|
modules: [
|
32
48
|
'@dargmuesli/nuxt-cookie-control',
|
49
|
+
'@nuxt/image',
|
50
|
+
'@nuxtjs/color-mode',
|
33
51
|
'@nuxtjs/html-validator',
|
34
52
|
'@nuxtjs/i18n',
|
35
53
|
'@nuxtjs/tailwindcss',
|
54
|
+
'@pinia/nuxt',
|
36
55
|
'nuxt-seo-kit-module',
|
37
56
|
],
|
38
57
|
nitro: {
|
@@ -46,14 +65,26 @@ export default defineNuxtConfig({
|
|
46
65
|
},
|
47
66
|
isInProduction: process.env.NODE_ENV === 'production',
|
48
67
|
isTesting: false,
|
68
|
+
stagingHost:
|
69
|
+
process.env.NODE_ENV !== 'production' &&
|
70
|
+
!process.env.NUXT_PUBLIC_STACK_DOMAIN
|
71
|
+
? 'localhost:3000'
|
72
|
+
: undefined,
|
49
73
|
},
|
50
74
|
},
|
51
75
|
typescript: {
|
52
76
|
shim: false,
|
53
|
-
|
77
|
+
// tsConfig: {
|
78
|
+
// compilerOptions: {
|
79
|
+
// esModuleInterop: true,
|
80
|
+
// },
|
81
|
+
// },
|
54
82
|
},
|
55
83
|
|
56
84
|
// modules
|
85
|
+
colorMode: {
|
86
|
+
classSuffix: '',
|
87
|
+
},
|
57
88
|
cookieControl: {
|
58
89
|
cookies: {
|
59
90
|
necessary: [
|
@@ -79,7 +110,19 @@ export default defineNuxtConfig({
|
|
79
110
|
de: 'Sprache',
|
80
111
|
en: 'Language',
|
81
112
|
},
|
82
|
-
targetCookieIds: [
|
113
|
+
targetCookieIds: [I18N_COOKIE_NAME],
|
114
|
+
},
|
115
|
+
{
|
116
|
+
description: {
|
117
|
+
de: 'Dieser Cookie von uns speichert die Zeitzone, in der sich das Gerät zu befinden scheint.',
|
118
|
+
en: 'This cookie of ours saves the timezone in which the device appears to be located.',
|
119
|
+
},
|
120
|
+
id: 't',
|
121
|
+
name: {
|
122
|
+
de: 'Zeitzone',
|
123
|
+
en: 'Timezone',
|
124
|
+
},
|
125
|
+
targetCookieIds: [TIMEZONE_COOKIE_NAME],
|
83
126
|
},
|
84
127
|
],
|
85
128
|
optional: [
|
@@ -101,18 +144,20 @@ export default defineNuxtConfig({
|
|
101
144
|
locales: ['en', 'de'],
|
102
145
|
},
|
103
146
|
htmlValidator: {
|
104
|
-
//
|
147
|
+
failOnError: false, // TODO: fix invalid html in nuxt html template (https://github.com/nuxt/nuxt/issues/22526)
|
105
148
|
logLevel: 'warning',
|
106
149
|
},
|
107
150
|
i18n: {
|
108
151
|
...I18N_MODULE_CONFIG,
|
109
152
|
defaultLocale: 'en', // Must be set for the default prefix_except_default prefix strategy.
|
110
153
|
detectBrowserLanguage: {
|
154
|
+
cookieKey: I18N_COOKIE_NAME,
|
111
155
|
cookieSecure: true,
|
112
156
|
},
|
113
157
|
},
|
114
158
|
linkChecker: {
|
115
|
-
|
159
|
+
debug: process.env.NODE_ENV === 'development',
|
160
|
+
failOnError: true,
|
116
161
|
},
|
117
162
|
seoKit: {
|
118
163
|
splash: false,
|
@@ -120,10 +165,11 @@ export default defineNuxtConfig({
|
|
120
165
|
site: {
|
121
166
|
debug: process.env.NODE_ENV === 'development',
|
122
167
|
name: SITE_NAME,
|
168
|
+
titleSeparator: '·',
|
123
169
|
url: BASE_URL,
|
124
170
|
},
|
125
171
|
sitemap: {
|
126
|
-
exclude: ['/api/**'],
|
172
|
+
exclude: ['/api/pages/**'],
|
127
173
|
},
|
128
174
|
tailwindcss: {
|
129
175
|
cssPath: join(currentDir, './assets/css/tailwind.css'),
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@dargmuesli/nuxt-vio",
|
3
|
-
"version": "
|
3
|
+
"version": "3.0.0-beta.10",
|
4
4
|
"type": "module",
|
5
5
|
"publishConfig": {
|
6
6
|
"access": "public"
|
@@ -8,16 +8,18 @@
|
|
8
8
|
"engines": {
|
9
9
|
"node": "20"
|
10
10
|
},
|
11
|
-
"packageManager": "pnpm@8.6.
|
11
|
+
"packageManager": "pnpm@8.6.12",
|
12
12
|
"files": [
|
13
13
|
"assets",
|
14
14
|
"components",
|
15
15
|
"composables",
|
16
16
|
"layouts",
|
17
17
|
"locales",
|
18
|
-
"server",
|
19
18
|
"pages",
|
20
19
|
"plugins",
|
20
|
+
"server",
|
21
|
+
"store",
|
22
|
+
"types",
|
21
23
|
"utils",
|
22
24
|
"app.config.ts",
|
23
25
|
"error.vue",
|
@@ -25,56 +27,66 @@
|
|
25
27
|
"nuxt.config.ts",
|
26
28
|
"tailwind.config.ts"
|
27
29
|
],
|
28
|
-
"main": "
|
30
|
+
"main": "nuxt.config.ts",
|
29
31
|
"scripts": {
|
30
|
-
"
|
31
|
-
"
|
32
|
-
"generate": "
|
33
|
-
"preview": "nuxi preview .playground",
|
34
|
-
"prepare": "pnpm husky install && pnpm nuxt prepare .playground",
|
35
|
-
"lint": "pnpm lint:js && pnpm lint:ts && pnpm lint:style",
|
32
|
+
"build": "nuxt build .playground",
|
33
|
+
"dev": "nuxt dev .playground",
|
34
|
+
"generate": "nuxt generate .playground",
|
36
35
|
"lint:fix": "pnpm lint:js --fix && pnpm lint:ts --fix && pnpm lint:style --fix",
|
37
36
|
"lint:js": "eslint --cache --ext .js,.ts,.vue --ignore-path .gitignore .",
|
38
|
-
"lint:staged": "
|
37
|
+
"lint:staged": "lint-staged",
|
39
38
|
"lint:style": "stylelint **/*.{vue,css} --ignore-path .gitignore",
|
40
|
-
"lint:ts": "nuxt typecheck"
|
39
|
+
"lint:ts": "nuxt typecheck",
|
40
|
+
"lint": "pnpm lint:js && pnpm lint:ts && pnpm lint:style",
|
41
|
+
"prepare": "nuxt prepare .playground",
|
42
|
+
"preview": "nuxt preview .playground"
|
41
43
|
},
|
42
44
|
"dependencies": {
|
43
45
|
"@dargmuesli/nuxt-cookie-control": "6.1.5",
|
44
|
-
"@dargmuesli/nuxt-vio": "link:",
|
45
46
|
"@http-util/status-i18n": "0.7.0",
|
47
|
+
"@nuxt/image": "1.0.0-rc.1",
|
48
|
+
"@nuxtjs/color-mode": "3.3.0",
|
46
49
|
"@nuxtjs/html-validator": "1.5.2",
|
47
|
-
"@nuxtjs/i18n": "8.0.0-rc.
|
50
|
+
"@nuxtjs/i18n": "8.0.0-rc.2",
|
48
51
|
"@nuxtjs/tailwindcss": "6.8.0",
|
52
|
+
"@pinia/nuxt": "0.4.11",
|
53
|
+
"@tailwindcss/forms": "0.5.4",
|
49
54
|
"@tailwindcss/typography": "0.5.9",
|
55
|
+
"@urql/core": "4.1.1",
|
56
|
+
"@urql/devtools": "2.0.3",
|
57
|
+
"@urql/exchange-graphcache": "6.3.1",
|
58
|
+
"@urql/vue": "1.1.2",
|
59
|
+
"@vuelidate/core": "2.0.3",
|
60
|
+
"@vuelidate/validators": "2.0.3",
|
61
|
+
"clipboard": "2.0.11",
|
62
|
+
"dayjs": "2.0.0-alpha.4",
|
63
|
+
"is-https": "4.0.0",
|
64
|
+
"jose": "4.14.4",
|
65
|
+
"marked": "7.0.1",
|
50
66
|
"nuxt-seo-kit-module": "2.0.0-beta.9",
|
67
|
+
"pinia": "2.1.6",
|
51
68
|
"sweetalert2": "11.7.20",
|
52
69
|
"vue-gtag": "2.0.1"
|
53
70
|
},
|
54
71
|
"devDependencies": {
|
55
|
-
"@commitlint/cli": "17.6.7",
|
56
|
-
"@commitlint/config-conventional": "17.6.7",
|
57
72
|
"@intlify/eslint-plugin-vue-i18n": "3.0.0-next.3",
|
58
73
|
"@nuxtjs/eslint-config-typescript": "12.0.0",
|
74
|
+
"@types/marked": "5.0.1",
|
59
75
|
"eslint": "8.46.0",
|
60
|
-
"eslint-config-prettier": "
|
76
|
+
"eslint-config-prettier": "9.0.0",
|
77
|
+
"eslint-plugin-compat": "4.1.4",
|
61
78
|
"eslint-plugin-nuxt": "4.0.0",
|
62
79
|
"eslint-plugin-prettier": "5.0.0",
|
63
80
|
"eslint-plugin-yml": "1.8.0",
|
64
|
-
"husky": "8.0.3",
|
65
81
|
"lint-staged": "13.2.3",
|
66
82
|
"nuxt": "3.6.5",
|
67
|
-
"prettier": "3.0.
|
83
|
+
"prettier": "3.0.1",
|
68
84
|
"stylelint": "15.10.2",
|
69
85
|
"stylelint-config-recommended-vue": "1.5.0",
|
70
86
|
"stylelint-config-standard": "34.0.0",
|
71
87
|
"stylelint-no-unsupported-browser-features": "7.0.0",
|
72
|
-
"
|
88
|
+
"tailwindcss": "3.3.3",
|
89
|
+
"vue": "3.3.4",
|
73
90
|
"vue-tsc": "1.8.8"
|
74
|
-
},
|
75
|
-
"pnpm": {
|
76
|
-
"overrides": {
|
77
|
-
"eslint-plugin-vue": "9.15.1"
|
78
|
-
}
|
79
91
|
}
|
80
92
|
}
|
package/pages/legal-notice.vue
CHANGED
package/pages/privacy-policy.vue
CHANGED
package/plugins/dayjs.ts
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
import dayjs from 'dayjs'
|
2
|
+
|
3
|
+
// workaround for [1]
|
4
|
+
import de from 'dayjs/locale/de'
|
5
|
+
// import 'dayjs/locale/de' does not make locale available
|
6
|
+
|
7
|
+
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'
|
8
|
+
import localizedFormat from 'dayjs/plugin/localizedFormat'
|
9
|
+
import timezone from 'dayjs/plugin/timezone'
|
10
|
+
import utc from 'dayjs/plugin/utc'
|
11
|
+
|
12
|
+
export default defineNuxtPlugin((_nuxtApp) => {
|
13
|
+
dayjs.extend(isSameOrBefore)
|
14
|
+
dayjs.extend(localizedFormat)
|
15
|
+
dayjs.extend(timezone)
|
16
|
+
dayjs.extend(utc)
|
17
|
+
|
18
|
+
// workaround for [1]
|
19
|
+
dayjs.locale(de)
|
20
|
+
// dayjs.locale(en) makes `format` error
|
21
|
+
|
22
|
+
return {
|
23
|
+
provide: {
|
24
|
+
dayjs,
|
25
|
+
},
|
26
|
+
}
|
27
|
+
})
|
28
|
+
|
29
|
+
/*
|
30
|
+
[1]
|
31
|
+
https://github.com/nuxt/framework/issues/7534#issuecomment-1248596609
|
32
|
+
https://github.com/nuxt/framework/issues/7206
|
33
|
+
https://github.com/maevsi/maevsi/issues/956
|
34
|
+
*/
|
package/plugins/gtag.client.ts
CHANGED
package/plugins/i18n.ts
ADDED
@@ -1,13 +1,44 @@
|
|
1
|
-
import { defineEventHandler } from 'h3'
|
1
|
+
import { appendHeader, defineEventHandler } from 'h3'
|
2
|
+
import type { H3Event } from 'h3'
|
3
|
+
import { AppConfig } from 'nuxt/schema'
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
+
import { TIMEZONE_HEADER_KEY } from '../../utils/constants'
|
6
|
+
import { getTimezone } from '../../utils/networking'
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
//
|
9
|
-
|
10
|
-
// 'Report-To',
|
11
|
-
// '{"group":"default","max_age":31536000,"endpoints":[{"url":"https://dargmuesli.report-uri.com/a/d/g"}],"include_subdomains":true}'
|
12
|
-
// )
|
8
|
+
export default defineEventHandler(async (event) => {
|
9
|
+
setRequestHeader(event, TIMEZONE_HEADER_KEY, await getTimezone(event))
|
10
|
+
// setContentSecurityPolicy(event);
|
11
|
+
setResponseHeaders(event)
|
13
12
|
})
|
13
|
+
|
14
|
+
// const setContentSecurityPolicy = (event: H3Event) => {
|
15
|
+
// const config = useAppConfig();
|
16
|
+
|
17
|
+
// appendHeader(
|
18
|
+
// event,
|
19
|
+
// "Content-Security-Policy",
|
20
|
+
// getCspAsString(config.public.vio.server.middleware.headers.csp)
|
21
|
+
// );
|
22
|
+
// };
|
23
|
+
|
24
|
+
const setRequestHeader = (event: H3Event, name: string, value?: string) => {
|
25
|
+
event.node.req.headers[name] = value
|
26
|
+
}
|
27
|
+
|
28
|
+
const setResponseHeaders = (event: H3Event) => {
|
29
|
+
const config = useAppConfig() as AppConfig
|
30
|
+
|
31
|
+
for (const entry of Object.entries(
|
32
|
+
config.vio.server.middleware.headers.csp.default,
|
33
|
+
)) {
|
34
|
+
appendHeader(event, entry[0], entry[1])
|
35
|
+
}
|
36
|
+
|
37
|
+
if (process.env.NODE_ENV === 'production') {
|
38
|
+
for (const entry of Object.entries(
|
39
|
+
config.vio.server.middleware.headers.csp.production,
|
40
|
+
)) {
|
41
|
+
appendHeader(event, entry[0], entry[1])
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
package/server/tsconfig.json
CHANGED
package/store/auth.ts
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
import { decodeJwt, JWTPayload } from 'jose'
|
2
|
+
import { defineStore } from 'pinia'
|
3
|
+
import { ref } from 'vue'
|
4
|
+
|
5
|
+
export const useVioAuthStore = defineStore('vio-auth', () => {
|
6
|
+
const jwt = ref<string>()
|
7
|
+
const jwtDecoded = ref<JWTPayload>()
|
8
|
+
const signedInUsername = ref<string>()
|
9
|
+
|
10
|
+
const jwtRemove = () => jwtSet(undefined)
|
11
|
+
|
12
|
+
const jwtSet = (jwtNew?: string) => {
|
13
|
+
const jwtDecodedNew = jwtNew !== undefined ? decodeJwt(jwtNew) : undefined
|
14
|
+
|
15
|
+
jwt.value = jwtNew
|
16
|
+
jwtDecoded.value = jwtDecodedNew
|
17
|
+
signedInUsername.value =
|
18
|
+
jwtDecodedNew?.role === 'vio_account' &&
|
19
|
+
jwtDecodedNew.exp !== undefined &&
|
20
|
+
jwtDecodedNew.exp > Math.floor(Date.now() / 1000)
|
21
|
+
? (jwtDecodedNew.username as string | undefined)
|
22
|
+
: undefined
|
23
|
+
}
|
24
|
+
|
25
|
+
return {
|
26
|
+
jwt,
|
27
|
+
jwtDecoded,
|
28
|
+
signedInUsername,
|
29
|
+
jwtRemove,
|
30
|
+
jwtSet,
|
31
|
+
}
|
32
|
+
})
|
package/tailwind.config.ts
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
import
|
2
|
-
import { PluginAPI } from 'tailwindcss/types/config'
|
1
|
+
import formsPlugin from '@tailwindcss/forms'
|
3
2
|
import typographyPlugin from '@tailwindcss/typography'
|
3
|
+
import type { Config } from 'tailwindcss'
|
4
|
+
import colors from 'tailwindcss/colors'
|
5
|
+
import type { PluginAPI } from 'tailwindcss/types/config'
|
4
6
|
|
5
|
-
const heading = (theme: PluginAPI['theme']) =>
|
6
|
-
(
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
const heading = (theme: PluginAPI['theme']): Record<string, string> => ({
|
8
|
+
fontWeight: theme('fontWeight.bold'),
|
9
|
+
// marginBottom: theme('margin.1'),
|
10
|
+
// marginTop: theme('margin.4'),
|
11
|
+
// set overflow truncate/ellipsis in the surrounding container, or larger fonts will be cut off due to their line-heights
|
12
|
+
})
|
11
13
|
|
12
14
|
const gray = colors.gray // or slate, zinc, neutral, stone
|
13
15
|
|
@@ -39,14 +41,42 @@ const prose = (theme: PluginAPI['theme']) => ({
|
|
39
41
|
})
|
40
42
|
|
41
43
|
export default {
|
44
|
+
content: [
|
45
|
+
'./components/**/*.{js,vue,ts}',
|
46
|
+
'./composables/**/*.{js,vue,ts}',
|
47
|
+
'./layouts/**/*.vue',
|
48
|
+
'./pages/**/*.vue',
|
49
|
+
'./plugins/**/*.{js,ts}',
|
50
|
+
// './nuxt.config.{js,ts}', // Does not work with i18n as of 2022-12-01
|
51
|
+
'./app.vue',
|
52
|
+
],
|
42
53
|
darkMode: 'class',
|
43
54
|
plugins: [
|
55
|
+
formsPlugin,
|
44
56
|
typographyPlugin,
|
45
|
-
({ addBase, addComponents, theme }: PluginAPI) => {
|
57
|
+
({ addBase, addComponents, addUtilities, theme }: PluginAPI) => {
|
46
58
|
addBase({
|
59
|
+
':disabled': {
|
60
|
+
cursor: theme('cursor.not-allowed'),
|
61
|
+
opacity: theme('opacity.50'),
|
62
|
+
},
|
63
|
+
'a[target="_blank"]:after': {
|
64
|
+
backgroundColor: 'currentColor',
|
65
|
+
content: '""',
|
66
|
+
display: 'inline-table', // inline-table centers the element vertically in the tiptap text area, instead of inline-block
|
67
|
+
mask: 'url(data:image/svg+xml;base64,PHN2ZyBhcmlhLWhpZGRlbj0idHJ1ZSIgZm9jdXNhYmxlPSJmYWxzZSIgZGF0YS1wcmVmaXg9ImZhcyIgZGF0YS1pY29uPSJhcnJvdy11cC1yaWdodC1mcm9tLXNxdWFyZSIgY2xhc3M9InN2Zy1pbmxpbmUtLWZhIGZhLWFycm93LXVwLXJpZ2h0LWZyb20tc3F1YXJlIiByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9ImN1cnJlbnRDb2xvciIgZD0iTTM4NCAzMjBjLTE3LjY3IDAtMzIgMTQuMzMtMzIgMzJ2OTZINjRWMTYwaDk2YzE3LjY3IDAgMzItMTQuMzIgMzItMzJzLTE0LjMzLTMyLTMyLTMyTDY0IDk2Yy0zNS4zNSAwLTY0IDI4LjY1LTY0IDY0VjQ0OGMwIDM1LjM0IDI4LjY1IDY0IDY0IDY0aDI4OGMzNS4zNSAwIDY0LTI4LjY2IDY0LTY0di05NkM0MTYgMzM0LjMgNDAxLjcgMzIwIDM4NCAzMjB6TTUwMi42IDkuMzY3QzQ5Ni44IDMuNTc4IDQ4OC44IDAgNDgwIDBoLTE2MGMtMTcuNjcgMC0zMS4xIDE0LjMyLTMxLjEgMzEuMWMwIDE3LjY3IDE0LjMyIDMxLjEgMzEuOTkgMzEuMWg4Mi43NUwxNzguNyAyOTAuN2MtMTIuNSAxMi41LTEyLjUgMzIuNzYgMCA0NS4yNkMxOTEuMiAzNDguNSAyMTEuNSAzNDguNSAyMjQgMzM2bDIyNC0yMjYuOFYxOTJjMCAxNy42NyAxNC4zMyAzMS4xIDMxLjEgMzEuMVM1MTIgMjA5LjcgNTEyIDE5MlYzMS4xQzUxMiAyMy4xNiA1MDguNCAxNS4xNiA1MDIuNiA5LjM2N3oiPjwvcGF0aD48L3N2Zz4K) no-repeat 50% 50%',
|
68
|
+
maskSize: 'cover',
|
69
|
+
height: theme('fontSize.xs'),
|
70
|
+
marginLeft: '5px',
|
71
|
+
width: theme('fontSize.xs'),
|
72
|
+
},
|
73
|
+
address: {
|
74
|
+
margin: theme('margin.4'),
|
75
|
+
},
|
47
76
|
h1: {
|
48
77
|
...heading(theme),
|
49
78
|
fontSize: theme('fontSize.4xl'),
|
79
|
+
// marginBottom: theme('margin.4'),
|
50
80
|
textAlign: 'center',
|
51
81
|
},
|
52
82
|
h2: {
|
@@ -70,14 +100,77 @@ export default {
|
|
70
100
|
},
|
71
101
|
})
|
72
102
|
addComponents({
|
103
|
+
'::placeholder': {
|
104
|
+
fontStyle: 'italic',
|
105
|
+
'.form-input&,.form-textarea&': {
|
106
|
+
opacity: '0.5',
|
107
|
+
},
|
108
|
+
},
|
109
|
+
'.form-input': {
|
110
|
+
appearance: 'none',
|
111
|
+
backgroundColor: theme('colors.gray.50'),
|
112
|
+
borderColor: theme('colors.gray.300'),
|
113
|
+
borderRadius: theme('borderRadius.DEFAULT'),
|
114
|
+
borderWidth: theme('borderWidth.DEFAULT'),
|
115
|
+
boxShadow: theme('boxShadow.sm'),
|
116
|
+
color: theme('colors.text.dark'),
|
117
|
+
lineHeight: theme('lineHeight.tight'),
|
118
|
+
padding: theme('padding.2') + ' ' + theme('padding.4'),
|
119
|
+
width: theme('width.full'),
|
120
|
+
'&:focus': {
|
121
|
+
backgroundColor: theme('colors.white'),
|
122
|
+
},
|
123
|
+
},
|
124
|
+
'.form-input-error': {
|
125
|
+
input: {
|
126
|
+
borderColor: theme('colors.red.500'),
|
127
|
+
},
|
128
|
+
},
|
129
|
+
'.form-input-success': {
|
130
|
+
input: {
|
131
|
+
borderColor: theme('colors.green.600'),
|
132
|
+
},
|
133
|
+
},
|
134
|
+
'.form-input-warning': {
|
135
|
+
input: {
|
136
|
+
borderColor: theme('colors.yellow.600'),
|
137
|
+
},
|
138
|
+
},
|
139
|
+
'.fullscreen': {
|
140
|
+
bottom: '0',
|
141
|
+
height: theme('height.full'),
|
142
|
+
left: '0',
|
143
|
+
position: 'absolute',
|
144
|
+
right: '0',
|
145
|
+
top: '0',
|
146
|
+
width: theme('width.full'),
|
147
|
+
},
|
73
148
|
'.object-position-custom': {
|
74
149
|
objectPosition: '50% 30%',
|
75
150
|
},
|
76
151
|
})
|
152
|
+
addUtilities({
|
153
|
+
'.disabled': {
|
154
|
+
cursor: theme('cursor.not-allowed'),
|
155
|
+
opacity: theme('opacity.50'),
|
156
|
+
},
|
157
|
+
'.max-w-xxs': {
|
158
|
+
maxWidth: '15rem',
|
159
|
+
},
|
160
|
+
'.min-w-xxs': {
|
161
|
+
minWidth: '15rem',
|
162
|
+
},
|
163
|
+
'.mb-20vh': {
|
164
|
+
marginBottom: '20vh',
|
165
|
+
},
|
166
|
+
})
|
77
167
|
},
|
78
168
|
],
|
79
169
|
theme: {
|
80
170
|
extend: {
|
171
|
+
animation: {
|
172
|
+
shake: 'shake 0.6s ease-in-out 0s 1 normal forwards running',
|
173
|
+
},
|
81
174
|
colors: {
|
82
175
|
background: {
|
83
176
|
bright: colors.white,
|
@@ -94,6 +187,34 @@ export default {
|
|
94
187
|
dark: gray['900'],
|
95
188
|
},
|
96
189
|
},
|
190
|
+
keyframes: {
|
191
|
+
shake: {
|
192
|
+
'0%': {
|
193
|
+
transform: 'translateX(0)',
|
194
|
+
},
|
195
|
+
'15%': {
|
196
|
+
transform: 'translateX(0.375rem)',
|
197
|
+
},
|
198
|
+
'30%': {
|
199
|
+
transform: 'translateX(-0.375rem)',
|
200
|
+
},
|
201
|
+
'45%': {
|
202
|
+
transform: 'translateX(0.375rem)',
|
203
|
+
},
|
204
|
+
'60%': {
|
205
|
+
transform: 'translateX(-0.375rem)',
|
206
|
+
},
|
207
|
+
'75%': {
|
208
|
+
transform: 'translateX(0.375rem)',
|
209
|
+
},
|
210
|
+
'90%': {
|
211
|
+
transform: 'translateX(-0.375rem)',
|
212
|
+
},
|
213
|
+
'100%': {
|
214
|
+
transform: 'translateX(0)',
|
215
|
+
},
|
216
|
+
},
|
217
|
+
},
|
97
218
|
screens: {
|
98
219
|
12: { raw: '(min-aspect-ratio: 2/1)' },
|
99
220
|
},
|
@@ -107,4 +228,4 @@ export default {
|
|
107
228
|
}),
|
108
229
|
},
|
109
230
|
},
|
110
|
-
}
|
231
|
+
} as Config
|
package/types/api.d.ts
ADDED
package/types/fetch.d.ts
ADDED
package/utils/constants.ts
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
export const SITE_NAME = 'Vio'
|
2
|
+
|
3
|
+
export const CACHE_VERSION = 'bOXMwoKlJr'
|
4
|
+
export const COOKIE_PREFIX = SITE_NAME.toLocaleLowerCase()
|
5
|
+
export const COOKIE_SEPARATOR = '_'
|
6
|
+
export const FETCH_RETRY_AMOUNT = 3
|
7
|
+
export const I18N_COOKIE_NAME = 'i18n_r'
|
1
8
|
export const I18N_MODULE_CONFIG = {
|
2
9
|
langDir: 'locales',
|
3
10
|
lazy: true,
|
@@ -20,4 +27,6 @@ export const I18N_VUE_CONFIG = {
|
|
20
27
|
fallbackWarn: false, // covered by linting
|
21
28
|
missingWarn: false, // covered by linting
|
22
29
|
}
|
23
|
-
export const
|
30
|
+
export const TIMEZONE_COOKIE_NAME = [COOKIE_PREFIX, 'tz'].join(COOKIE_SEPARATOR)
|
31
|
+
export const TIMEZONE_HEADER_KEY = `X-${SITE_NAME}-Timezone`
|
32
|
+
export const VALIDATION_SUGGESTION_TITLE_LENGTH_MAXIMUM = 300
|