mirror of
https://github.com/ArthurDanjou/Hermes.git
synced 2026-01-14 12:14:38 +01:00
Initial commit 🚀
This commit is contained in:
3
.eslintignore
Normal file
3
.eslintignore
Normal file
@@ -0,0 +1,3 @@
|
||||
dist
|
||||
node_modules
|
||||
public
|
||||
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
.DS_Store
|
||||
.vite-ssg-dist
|
||||
.vite-ssg-temp
|
||||
*.local
|
||||
dist
|
||||
dist-ssr
|
||||
node_modules
|
||||
# intellij stuff
|
||||
.idea/
|
||||
# logs
|
||||
*.log
|
||||
/.env
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2021 Anthony Fu
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
158
auto-imports.d.ts
vendored
Normal file
158
auto-imports.d.ts
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
// Generated by 'unplugin-auto-import'
|
||||
// We suggest you to commit this file into source control
|
||||
declare global {
|
||||
const onActivated: typeof import('vue')['onActivated']
|
||||
const onBeforeMount: typeof import('vue')['onBeforeMount']
|
||||
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
|
||||
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
|
||||
const onMounted: typeof import('vue')['onMounted']
|
||||
const onUnmounted: typeof import('vue')['onUnmounted']
|
||||
const onUpdated: typeof import('vue')['onUpdated']
|
||||
const computed: typeof import('vue')['computed']
|
||||
const customRef: typeof import('vue')['customRef']
|
||||
const isReadonly: typeof import('vue')['isReadonly']
|
||||
const isRef: typeof import('vue')['isRef']
|
||||
const markRaw: typeof import('vue')['markRaw']
|
||||
const reactive: typeof import('vue')['reactive']
|
||||
const readonly: typeof import('vue')['readonly']
|
||||
const ref: typeof import('vue')['ref']
|
||||
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||
const shallowRef: typeof import('vue')['shallowRef']
|
||||
const toRaw: typeof import('vue')['toRaw']
|
||||
const toRef: typeof import('vue')['toRef']
|
||||
const toRefs: typeof import('vue')['toRefs']
|
||||
const unref: typeof import('vue')['unref']
|
||||
const watch: typeof import('vue')['watch']
|
||||
const watchEffect: typeof import('vue')['watchEffect']
|
||||
const defineComponent: typeof import('vue')['defineComponent']
|
||||
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||
const h: typeof import('vue')['h']
|
||||
const inject: typeof import('vue')['inject']
|
||||
const nextTick: typeof import('vue')['nextTick']
|
||||
const provide: typeof import('vue')['provide']
|
||||
const useCssModule: typeof import('vue')['useCssModule']
|
||||
const createApp: typeof import('vue')['createApp']
|
||||
const triggerRef: typeof import('vue')['triggerRef']
|
||||
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
|
||||
const onDeactivated: typeof import('vue')['onDeactivated']
|
||||
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
|
||||
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
|
||||
const onRenderTracked: typeof import('vue')['onRenderTracked']
|
||||
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
|
||||
const useRouter: typeof import('vue-router')['useRouter']
|
||||
const useRoute: typeof import('vue-router')['useRoute']
|
||||
const useI18n: typeof import('vue-i18n')['useI18n']
|
||||
const useHead: typeof import('@vueuse/head')['useHead']
|
||||
const biSyncRef: typeof import('@vueuse/core')['biSyncRef']
|
||||
const controlledComputed: typeof import('@vueuse/core')['controlledComputed']
|
||||
const controlledRef: typeof import('@vueuse/core')['controlledRef']
|
||||
const createEventHook: typeof import('@vueuse/core')['createEventHook']
|
||||
const createGlobalState: typeof import('@vueuse/core')['createGlobalState']
|
||||
const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable']
|
||||
const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch']
|
||||
const extendRef: typeof import('@vueuse/core')['extendRef']
|
||||
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
|
||||
const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable']
|
||||
const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
|
||||
const reactify: typeof import('@vueuse/core')['reactify']
|
||||
const reactifyObject: typeof import('@vueuse/core')['reactifyObject']
|
||||
const reactivePick: typeof import('@vueuse/core')['reactivePick']
|
||||
const syncRef: typeof import('@vueuse/core')['syncRef']
|
||||
const throttledWatch: typeof import('@vueuse/core')['throttledWatch']
|
||||
const toReactive: typeof import('@vueuse/core')['toReactive']
|
||||
const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted']
|
||||
const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose']
|
||||
const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted']
|
||||
const until: typeof import('@vueuse/core')['until']
|
||||
const useCounter: typeof import('@vueuse/core')['useCounter']
|
||||
const useDebounce: typeof import('@vueuse/core')['useDebounce']
|
||||
const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn']
|
||||
const useInterval: typeof import('@vueuse/core')['useInterval']
|
||||
const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn']
|
||||
const useLastChanged: typeof import('@vueuse/core')['useLastChanged']
|
||||
const useThrottle: typeof import('@vueuse/core')['useThrottle']
|
||||
const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn']
|
||||
const useTimeout: typeof import('@vueuse/core')['useTimeout']
|
||||
const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn']
|
||||
const useToggle: typeof import('@vueuse/core')['useToggle']
|
||||
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
|
||||
const whenever: typeof import('@vueuse/core')['whenever']
|
||||
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
|
||||
const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
|
||||
const computedInject: typeof import('@vueuse/core')['computedInject']
|
||||
const onClickOutside: typeof import('@vueuse/core')['onClickOutside']
|
||||
const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke']
|
||||
const onStartTyping: typeof import('@vueuse/core')['onStartTyping']
|
||||
const templateRef: typeof import('@vueuse/core')['templateRef']
|
||||
const unrefElement: typeof import('@vueuse/core')['unrefElement']
|
||||
const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
|
||||
const useAsyncState: typeof import('@vueuse/core')['useAsyncState']
|
||||
const useBattery: typeof import('@vueuse/core')['useBattery']
|
||||
const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints']
|
||||
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
|
||||
const useClipboard: typeof import('@vueuse/core')['useClipboard']
|
||||
const useCssVar: typeof import('@vueuse/core')['useCssVar']
|
||||
const useDark: typeof import('@vueuse/core')['useDark']
|
||||
const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion']
|
||||
const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation']
|
||||
const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio']
|
||||
const useDevicesList: typeof import('@vueuse/core')['useDevicesList']
|
||||
const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility']
|
||||
const useElementBounding: typeof import('@vueuse/core')['useElementBounding']
|
||||
const useElementSize: typeof import('@vueuse/core')['useElementSize']
|
||||
const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility']
|
||||
const useEventBus: typeof import('@vueuse/core')['useEventBus']
|
||||
const useEventListener: typeof import('@vueuse/core')['useEventListener']
|
||||
const useEventSource: typeof import('@vueuse/core')['useEventSource']
|
||||
const useFavicon: typeof import('@vueuse/core')['useFavicon']
|
||||
const useFetch: typeof import('@vueuse/core')['useFetch']
|
||||
const useFullscreen: typeof import('@vueuse/core')['useFullscreen']
|
||||
const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
|
||||
const useIdle: typeof import('@vueuse/core')['useIdle']
|
||||
const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver']
|
||||
const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage']
|
||||
const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys']
|
||||
const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory']
|
||||
const useMediaControls: typeof import('@vueuse/core')['useMediaControls']
|
||||
const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery']
|
||||
const useMouse: typeof import('@vueuse/core')['useMouse']
|
||||
const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement']
|
||||
const useMousePressed: typeof import('@vueuse/core')['useMousePressed']
|
||||
const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver']
|
||||
const useNetwork: typeof import('@vueuse/core')['useNetwork']
|
||||
const useNow: typeof import('@vueuse/core')['useNow']
|
||||
const useOnline: typeof import('@vueuse/core')['useOnline']
|
||||
const usePageLeave: typeof import('@vueuse/core')['usePageLeave']
|
||||
const useParallax: typeof import('@vueuse/core')['useParallax']
|
||||
const usePermission: typeof import('@vueuse/core')['usePermission']
|
||||
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
|
||||
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
|
||||
const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark']
|
||||
const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages']
|
||||
const useRafFn: typeof import('@vueuse/core')['useRafFn']
|
||||
const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
|
||||
const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver']
|
||||
const useScriptTag: typeof import('@vueuse/core')['useScriptTag']
|
||||
const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage']
|
||||
const useShare: typeof import('@vueuse/core')['useShare']
|
||||
const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition']
|
||||
const useStorage: typeof import('@vueuse/core')['useStorage']
|
||||
const useSwipe: typeof import('@vueuse/core')['useSwipe']
|
||||
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
|
||||
const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo']
|
||||
const useTimestamp: typeof import('@vueuse/core')['useTimestamp']
|
||||
const useTitle: typeof import('@vueuse/core')['useTitle']
|
||||
const useTransition: typeof import('@vueuse/core')['useTransition']
|
||||
const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
|
||||
const useUserMedia: typeof import('@vueuse/core')['useUserMedia']
|
||||
const useVModel: typeof import('@vueuse/core')['useVModel']
|
||||
const useVModels: typeof import('@vueuse/core')['useVModels']
|
||||
const useWebSocket: typeof import('@vueuse/core')['useWebSocket']
|
||||
const useWebWorker: typeof import('@vueuse/core')['useWebWorker']
|
||||
const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn']
|
||||
const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus']
|
||||
const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll']
|
||||
const useWindowSize: typeof import('@vueuse/core')['useWindowSize']
|
||||
}
|
||||
export {}
|
||||
60
components.d.ts
vendored
Normal file
60
components.d.ts
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// generated by unplugin-vue-components
|
||||
// We suggest you to commit this file into source control
|
||||
// Read more: https://github.com/vuejs/vue-next/pull/3399
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
ArrowIcon: typeof import('./src/components/icons/ArrowIcon.vue')['default']
|
||||
BrushIcon: typeof import('./src/components/icons/BrushIcon.vue')['default']
|
||||
CarbonCampsite: typeof import('virtual:vite-icons/carbon/campsite')['default']
|
||||
CarbonDicomOverlay: typeof import('virtual:vite-icons/carbon/dicom-overlay')['default']
|
||||
CarbonLanguage: typeof import('virtual:vite-icons/carbon/language')['default']
|
||||
CarbonLogoGithub: typeof import('virtual:vite-icons/carbon/logo-github')['default']
|
||||
CarbonMoon: typeof import('virtual:vite-icons/carbon/moon')['default']
|
||||
CarbonPedestrian: typeof import('virtual:vite-icons/carbon/pedestrian')['default']
|
||||
CarbonSun: typeof import('virtual:vite-icons/carbon/sun')['default']
|
||||
CarbonWarning: typeof import('virtual:vite-icons/carbon/warning')['default']
|
||||
CloudIcon: typeof import('./src/components/icons/CloudIcon.vue')['default']
|
||||
CollapseIcon: typeof import('./src/components/icons/CollapseIcon.vue')['default']
|
||||
ColorModeButton: typeof import('./src/components/ColorModeButton.vue')['default']
|
||||
CompassIcon: typeof import('./src/components/icons/CompassIcon.vue')['default']
|
||||
CrownIcon: typeof import('./src/components/icons/CrownIcon.vue')['default']
|
||||
CubeIcon: typeof import('./src/components/icons/CubeIcon.vue')['default']
|
||||
DegreeHatIcon: typeof import('./src/components/icons/DegreeHatIcon.vue')['default']
|
||||
DeleteButton: typeof import('./src/components/DeleteButton.vue')['default']
|
||||
FlagIcon: typeof import('./src/components/icons/FlagIcon.vue')['default']
|
||||
Footer: typeof import('./src/components/Footer.vue')['default']
|
||||
GearIcon: typeof import('./src/components/icons/GearIcon.vue')['default']
|
||||
GlobeIcon: typeof import('./src/components/icons/GlobeIcon.vue')['default']
|
||||
GraduationIcon: typeof import('./src/components/icons/GraduationIcon.vue')['default']
|
||||
GraphIcon: typeof import('./src/components/icons/GraphIcon.vue')['default']
|
||||
Header: typeof import('./src/components/Header.vue')['default']
|
||||
HomeIcon: typeof import('./src/components/icons/HomeIcon.vue')['default']
|
||||
LanguageButton: typeof import('./src/components/LanguageButton.vue')['default']
|
||||
LightbulbIcon: typeof import('./src/components/icons/LightbulbIcon.vue')['default']
|
||||
LinkIco: typeof import('./src/components/icons/LinkIco.vue')['default']
|
||||
LinkIcon: typeof import('./src/components/icons/LinkIcon.vue')['default']
|
||||
Logo: typeof import('./src/components/Logo.vue')['default']
|
||||
MediaIcon: typeof import('./src/components/icons/MediaIcon.vue')['default']
|
||||
MoonIcon: typeof import('./src/components/icons/MoonIcon.vue')['default']
|
||||
NewspaperIcon: typeof import('./src/components/icons/NewspaperIcon.vue')['default']
|
||||
PageTitle: typeof import('./src/components/PageTitle.vue')['default']
|
||||
PencilIcon: typeof import('./src/components/icons/PencilIcon.vue')['default']
|
||||
PenIcon: typeof import('./src/components/icons/PenIcon.vue')['default']
|
||||
PresentationIcon: typeof import('./src/components/icons/PresentationIcon.vue')['default']
|
||||
SideBar: typeof import('./src/components/SideBar.vue')['default']
|
||||
SideBarCollapse: typeof import('./src/components/SideBarCollapse.vue')['default']
|
||||
SideBarCollapseItem: typeof import('./src/components/SideBarCollapseItem.vue')['default']
|
||||
SideBarDivider: typeof import('./src/components/SideBarDivider.vue')['default']
|
||||
SideBarItem: typeof import('./src/components/SideBarItem.vue')['default']
|
||||
StarIcon: typeof import('./src/components/icons/StarIcon.vue')['default']
|
||||
SunIcon: typeof import('./src/components/icons/SunIcon.vue')['default']
|
||||
TagIcon: typeof import('./src/components/icons/TagIcon.vue')['default']
|
||||
TranslateIcon: typeof import('./src/components/icons/TranslateIcon.vue')['default']
|
||||
TrashIcon: typeof import('./src/components/icons/TrashIcon.vue')['default']
|
||||
UpdateButton: typeof import('./src/components/UpdateButton.vue')['default']
|
||||
UsersIcon: typeof import('./src/components/icons/UsersIcon.vue')['default']
|
||||
}
|
||||
}
|
||||
|
||||
export { }
|
||||
24
index.html
Normal file
24
index.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
||||
<link rel="apple-touch-icon" href="/pwa-192x192.png">
|
||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#00aba9">
|
||||
<meta name="msapplication-TileColor" content="#00aba9">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script>
|
||||
(function() {
|
||||
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
const setting = localStorage.getItem('color-schema') || 'auto'
|
||||
if (setting === 'dark' || (prefersDark && setting !== 'light'))
|
||||
document.documentElement.classList.toggle('dark', true)
|
||||
})()
|
||||
</script>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
47
locales/en.json
Normal file
47
locales/en.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"hello": "HomePage",
|
||||
|
||||
"logo": {
|
||||
"short": "H.",
|
||||
"long": "Hermes"
|
||||
},
|
||||
|
||||
"sidebar": {
|
||||
"home": "Home",
|
||||
"users": "Users",
|
||||
"subscribers": "Subscribers",
|
||||
"translations": "Translations",
|
||||
"files": "Files",
|
||||
|
||||
"ares": "Ares",
|
||||
"announces": "Announces",
|
||||
"informations": "Informations",
|
||||
"skills": "Skills",
|
||||
"formations": "Formations",
|
||||
"experiences": "Experiences",
|
||||
"tags": "Tags",
|
||||
"colors": "Colors",
|
||||
"posts": "Posts",
|
||||
|
||||
"artemis": "Artemis",
|
||||
"links": "Links",
|
||||
"stats": "Statistics",
|
||||
|
||||
"tools": "Tools",
|
||||
"apollon": "Apollon"
|
||||
},
|
||||
|
||||
"login": {
|
||||
"form": {
|
||||
"email": "Email Address",
|
||||
"password": "Password",
|
||||
"login": "Login"
|
||||
},
|
||||
"forget": "Forgot password?",
|
||||
"no_account": "You don't have an account?",
|
||||
"ask": "Ask for one.",
|
||||
"secure": "Secure login process ✅",
|
||||
"credits": "© 2021 - Hermes by ArtDanjProduction.",
|
||||
"credentials": "Your credentials are incorrect ❌"
|
||||
}
|
||||
}
|
||||
47
locales/fr.json
Normal file
47
locales/fr.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"hello": "Page d'accueil",
|
||||
|
||||
"logo": {
|
||||
"short": "H.",
|
||||
"long": "Hermes"
|
||||
},
|
||||
|
||||
"sidebar": {
|
||||
"home": "Accueil",
|
||||
"users": "Utilisateurs",
|
||||
"subscribers": "Abonnés",
|
||||
"translations": "Traductions",
|
||||
"files": "Fichiers",
|
||||
|
||||
"ares": "Ares",
|
||||
"announces": "Annonces",
|
||||
"informations": "Informations",
|
||||
"skills": "Compétences",
|
||||
"formations": "Formations",
|
||||
"experiences": "Expériences",
|
||||
"tags": "Tags",
|
||||
"colors": "Couleurs",
|
||||
"posts": "Articles",
|
||||
|
||||
"artemis": "Artemis",
|
||||
"links": "Liens",
|
||||
"stats": "Statistiques",
|
||||
|
||||
"tools": "Outils",
|
||||
"apollon": "Apollon"
|
||||
},
|
||||
|
||||
"login": {
|
||||
"form": {
|
||||
"email": "Adresse email",
|
||||
"password": "Mot de passe",
|
||||
"login": "Connexion"
|
||||
},
|
||||
"forget": "Mot de passe oublié ?",
|
||||
"no_account": "Vous n'avez pas de compte ?",
|
||||
"ask": "Demandez-en un.",
|
||||
"secure": "Processus de connexion sécurisé ✅",
|
||||
"credits": "© 2021 - Hermes par ArtDanjProduction.",
|
||||
"credentials": "Vos identifiants sont incorrects ❌"
|
||||
}
|
||||
}
|
||||
53
package.json
Normal file
53
package.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --port 3333 --open",
|
||||
"build": "cross-env NODE_ENV=production vite-ssg build",
|
||||
"preview": "vite preview",
|
||||
"preview-https": "serve dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tiptap/starter-kit": "^2.0.0-beta.101",
|
||||
"@tiptap/vue-3": "^2.0.0-beta.56",
|
||||
"@vueuse/core": "^6.0.0",
|
||||
"@vueuse/head": "^0.6.0",
|
||||
"axios": "^0.21.4",
|
||||
"nprogress": "^0.2.0",
|
||||
"prism-theme-vars": "^0.2.2",
|
||||
"sass": "^1.39.0",
|
||||
"vue": "^3.2.2",
|
||||
"vue-demi": "^0.11.3",
|
||||
"vue-global-api": "^0.4.1",
|
||||
"vue-i18n": "^9.1.7",
|
||||
"vue-router": "^4.0.11",
|
||||
"vuex": "^4.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^0.7.0",
|
||||
"@iconify/json": "^1.1.398",
|
||||
"@intlify/vite-plugin-vue-i18n": "^2.4.0",
|
||||
"@types/markdown-it-link-attributes": "^3.0.1",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@vitejs/plugin-vue": "^1.6.1",
|
||||
"@vue/compiler-sfc": "^3.2.9",
|
||||
"@vue/server-renderer": "^3.2.9",
|
||||
"critters": "^0.0.10",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^7.32.0",
|
||||
"https-localhost": "^4.6.5",
|
||||
"markdown-it-link-attributes": "^3.0.0",
|
||||
"markdown-it-prism": "^2.2.0",
|
||||
"typescript": "^4.4.2",
|
||||
"unplugin-auto-import": "^0.4.5",
|
||||
"unplugin-icons": "^0.7.6",
|
||||
"unplugin-vue-components": "^0.14.13",
|
||||
"vite": "^2.5.4",
|
||||
"vite-plugin-md": "^0.11.0",
|
||||
"vite-plugin-pages": "^0.18.0",
|
||||
"vite-plugin-pwa": "^0.11.2",
|
||||
"vite-plugin-vue-layouts": "^0.4.1",
|
||||
"vite-plugin-windicss": "^1.4.2",
|
||||
"vite-ssg": "^0.15.1",
|
||||
"vue-tsc": "^0.3.0"
|
||||
}
|
||||
}
|
||||
9
public/favicon.svg
Normal file
9
public/favicon.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<style>
|
||||
path { fill: #222; }
|
||||
@media (prefers-color-scheme: dark) {
|
||||
path { fill: #ffffff; }
|
||||
}
|
||||
</style>
|
||||
<path d="M27.562 26L17.17 8.928l2.366-3.888L17.828 4L16 7.005L14.17 4l-1.708 1.04l2.366 3.888L4.438 26H2v2h28v-2zM16 10.85L25.22 26H17v-8h-2v8H6.78z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 347 B |
BIN
public/pwa-192x192.png
Normal file
BIN
public/pwa-192x192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
BIN
public/pwa-512x512.png
Normal file
BIN
public/pwa-512x512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
2
public/robots.txt
Normal file
2
public/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
41
public/safari-pinned-tab.svg
Normal file
41
public/safari-pinned-tab.svg
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="700.000000pt" height="700.000000pt" viewBox="0 0 700.000000 700.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,700.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M2916 6015 c-93 -57 -173 -108 -178 -113 -6 -6 7 -36 33 -78 23 -38
|
||||
86 -141 139 -229 54 -88 135 -221 180 -295 46 -74 94 -155 108 -180 14 -25 29
|
||||
-52 35 -60 7 -12 -9 -45 -62 -130 -39 -63 -85 -140 -103 -170 -18 -30 -117
|
||||
-194 -222 -365 -104 -170 -199 -326 -210 -346 -12 -19 -61 -102 -111 -183 -49
|
||||
-81 -101 -166 -115 -189 -14 -23 -39 -64 -55 -90 -17 -27 -77 -126 -134 -220
|
||||
-57 -95 -127 -210 -156 -257 -194 -315 -325 -533 -325 -541 0 -5 -4 -9 -10 -9
|
||||
-5 0 -10 -4 -10 -9 0 -5 -55 -98 -121 -207 -247 -404 -403 -660 -416 -684 -8
|
||||
-14 -58 -97 -112 -185 l-98 -160 -189 -2 c-104 -1 -225 -2 -269 -2 l-80 -1 1
|
||||
-210 c0 -116 4 -213 8 -218 11 -11 6107 -9 6114 2 8 13 8 406 0 419 -4 7 -88
|
||||
10 -265 9 l-259 -2 -50 77 c-27 43 -54 87 -60 98 -6 11 -62 103 -124 205 -62
|
||||
102 -120 197 -129 212 -9 16 -85 142 -170 280 -85 139 -160 262 -165 273 -6
|
||||
11 -13 22 -16 25 -3 3 -30 46 -59 95 -30 50 -102 169 -161 265 -59 96 -240
|
||||
393 -402 660 -163 267 -371 609 -463 760 -92 151 -194 318 -225 370 -31 52
|
||||
-101 167 -155 255 l-97 160 27 50 c16 27 32 55 36 61 5 5 38 59 74 120 36 60
|
||||
69 116 74 124 5 8 75 122 155 253 81 131 144 242 141 247 -4 7 -114 76 -183
|
||||
115 -10 6 -52 32 -95 58 -42 27 -81 46 -87 42 -8 -5 -94 -140 -140 -219 -19
|
||||
-33 -221 -365 -246 -404 -15 -22 -18 -18 -111 135 -52 87 -123 203 -157 258
|
||||
-67 108 -67 110 -111 184 -16 28 -34 51 -40 50 -5 0 -86 -47 -179 -104z m739
|
||||
-1642 c319 -526 519 -854 637 -1046 43 -70 78 -130 78 -133 0 -2 5 -10 10 -17
|
||||
6 -7 69 -109 140 -227 72 -118 134 -222 139 -230 5 -8 55 -89 111 -180 56 -91
|
||||
105 -172 110 -180 9 -14 52 -84 270 -445 54 -88 135 -221 180 -295 46 -74 91
|
||||
-148 100 -165 9 -16 31 -53 48 -81 18 -28 32 -54 32 -57 0 -3 -403 -6 -895 -5
|
||||
l-895 0 0 81 c-1 45 -1 439 -1 875 l0 792 -37 1 c-57 1 -344 1 -374 0 l-27 -1
|
||||
0 -832 c0 -458 0 -852 0 -875 l-1 -42 -895 1 c-492 0 -895 3 -895 5 0 9 115
|
||||
198 122 201 5 2 8 7 8 12 0 5 23 46 51 92 28 46 78 128 112 183 33 55 70 116
|
||||
82 135 12 19 132 215 265 435 133 220 266 438 295 485 65 105 206 338 220 362
|
||||
6 10 172 284 370 608 198 325 387 635 420 690 33 55 62 100 65 100 3 0 73
|
||||
-111 155 -247z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
23
src/App.vue
Normal file
23
src/App.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import { useHead } from '@vueuse/head'
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
// https://github.com/vueuse/head
|
||||
// you can use this to manipulate the document head in any components,
|
||||
// they will be rendered correctly in the html results with vite-ssg
|
||||
useHead({
|
||||
title: 'Hermes - ArtDanjProduction',
|
||||
meta: [
|
||||
{ name: 'description', content: 'Hermes is my personal dashboard used to manage my services.' },
|
||||
],
|
||||
})
|
||||
|
||||
const store = useStore()
|
||||
onBeforeMount(() => {
|
||||
store.dispatch('FETCH_USER')
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<router-view />
|
||||
</template>
|
||||
17
src/components/ColorModeButton.vue
Normal file
17
src/components/ColorModeButton.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div
|
||||
class="h-9 w-9 cursor-pointer flex items-center p-1.5 rounded-xl hover:bg-gray-300 dark:hover:bg-dark-400 duration-200"
|
||||
@click="toggleDark"
|
||||
>
|
||||
<div v-if="isDark">
|
||||
<SunIcon />
|
||||
</div>
|
||||
<div v-else>
|
||||
<MoonIcon />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { isDark, toggleDark } from '~/logic'
|
||||
</script>
|
||||
11
src/components/DeleteButton.vue
Normal file
11
src/components/DeleteButton.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div class="flex">
|
||||
<div class="bg-red-300 hover:bg-red-500 duration-500 cursor-pointer py-2 px-2.5 rounded-lg">
|
||||
<TrashIcon />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
15
src/components/Footer.vue
Normal file
15
src/components/Footer.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<footer class="">
|
||||
FOOTER
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Footer',
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
35
src/components/Header.vue
Normal file
35
src/components/Header.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<header class="fixed bg-white dark:bg-dark-900 top-0 w-full h-16 border-b border-gray-200 dark:border-gray-800">
|
||||
<div class="h-full flex items-center justify-center">
|
||||
<div
|
||||
class="bg-white dark:bg-dark-900 py-1 cursor-pointer z-10 absolute top-4 -left-3 transition-transform delay-300 duration-300 transform flex justify-center items-center"
|
||||
:class="opened ? 'rotate-540' : 'rotate-0'"
|
||||
@click="setOpened(!opened)"
|
||||
>
|
||||
<ArrowIcon />
|
||||
</div>
|
||||
<h1>Header</h1>
|
||||
<ColorModeButton class="mx-2" />
|
||||
<LanguageButton class="mx-2" />
|
||||
<div
|
||||
class="hover:text-red-400 cursor-pointer mx-4 duration-500"
|
||||
@click.prevent="logout"
|
||||
>
|
||||
Logout
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useStore } from 'vuex'
|
||||
import { useAuth } from '~/logic/auth'
|
||||
|
||||
const store = useStore()
|
||||
const opened = computed(() => store.getters.isOpened)
|
||||
const setOpened = (value: boolean) => {
|
||||
store.commit('SET_OPENED', value)
|
||||
}
|
||||
|
||||
const { logout, } = useAuth()
|
||||
</script>
|
||||
18
src/components/LanguageButton.vue
Normal file
18
src/components/LanguageButton.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div
|
||||
class="h-9 w-9 cursor-pointer flex items-center justify-center p-1.5 rounded-xl hover:bg-gray-300 duration-200 dark:hover:bg-dark-400"
|
||||
@click="changeLanguage()"
|
||||
>
|
||||
<FlagIcon :french="isFrench" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { locale } = useI18n()
|
||||
const isFrench = computed(() => locale.value === 'fr')
|
||||
const changeLanguage = () => {
|
||||
locale.value = locale.value === 'fr' ? 'en' : 'fr'
|
||||
}
|
||||
</script>
|
||||
23
src/components/Logo.vue
Normal file
23
src/components/Logo.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="opened && router.currentRoute.name !== 'login'"
|
||||
class="font-black text-xl tracking-widest"
|
||||
>
|
||||
{{ t('logo.long') }}
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="font-black text-xl tracking-widest"
|
||||
>
|
||||
{{ t('logo.short') }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
const router = useRouter()
|
||||
const store = useStore()
|
||||
const opened = computed(() => store.getters.isOpened)
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
19
src/components/PageTitle.vue
Normal file
19
src/components/PageTitle.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<div class="flex items-center mb-8">
|
||||
<div class="mr-4 text-lg flex items-center justify-center p-2 bg-red-400 dark:bg-amber-400 rounded-xl text-black">
|
||||
<slot />
|
||||
</div>
|
||||
<h1 class="font-medium text-4xl">
|
||||
{{ title }}
|
||||
</h1>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: 'Title',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
99
src/components/SideBar.vue
Normal file
99
src/components/SideBar.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<div>
|
||||
<aside
|
||||
class="fixed bg-white dark:bg-dark-900 top-0 left-0 duration-300 h-screen overflow-y-scroll select-none border-r border-gray-200 dark:border-gray-800"
|
||||
:class="opened ? 'w-64' : 'w-20'"
|
||||
>
|
||||
<div class="my-8 flex justify-center">
|
||||
<Logo />
|
||||
</div>
|
||||
<nav
|
||||
class="flex flex-col p-4 duration-300"
|
||||
:class="{'items-center': !opened}"
|
||||
>
|
||||
<SideBarItem title="home" link="/">
|
||||
<HomeIcon />
|
||||
</SideBarItem>
|
||||
<SideBarItem title="users" link="users">
|
||||
<UsersIcon />
|
||||
</SideBarItem>
|
||||
<SideBarItem title="subscribers" link="subscribers">
|
||||
<StarIcon />
|
||||
</SideBarItem>
|
||||
<SideBarItem title="translations" link="translations">
|
||||
<TranslateIcon />
|
||||
</SideBarItem>
|
||||
<SideBarItem title="files" link="files">
|
||||
<MediaIcon />
|
||||
</SideBarItem>
|
||||
<SideBarDivider />
|
||||
<SideBarCollapse title="ares">
|
||||
<template #icon>
|
||||
<GlobeIcon />
|
||||
</template>
|
||||
<template #children>
|
||||
<SideBarCollapseItem title="announces" link="announces">
|
||||
<NewspaperIcon />
|
||||
</SideBarCollapseItem>
|
||||
<SideBarCollapseItem title="informations" link="informations">
|
||||
<CrownIcon />
|
||||
</SideBarCollapseItem>
|
||||
<SideBarCollapseItem title="skills" link="skills">
|
||||
<CubeIcon />
|
||||
</SideBarCollapseItem>
|
||||
<SideBarCollapseItem title="formations" link="formations">
|
||||
<DegreeHatIcon />
|
||||
</SideBarCollapseItem>
|
||||
<SideBarCollapseItem title="experiences" link="experiences">
|
||||
<PresentationIcon />
|
||||
</SideBarCollapseItem>
|
||||
<SideBarCollapseItem title="tags" link="tags">
|
||||
<TagIcon />
|
||||
</SideBarCollapseItem>
|
||||
<SideBarCollapseItem title="colors" link="colors">
|
||||
<BrushIcon />
|
||||
</SideBarCollapseItem>
|
||||
<SideBarCollapseItem title="posts" link="posts">
|
||||
<PenIcon />
|
||||
</SideBarCollapseItem>
|
||||
</template>
|
||||
</SideBarCollapse>
|
||||
<SideBarDivider />
|
||||
<SideBarCollapse title="artemis">
|
||||
<template #icon>
|
||||
<CompassIcon />
|
||||
</template>
|
||||
<template #children>
|
||||
<SideBarCollapseItem title="links" link="links">
|
||||
<LinkIcon />
|
||||
</SideBarCollapseItem>
|
||||
<SideBarCollapseItem title="stats" link="statistiques">
|
||||
<GraphIcon />
|
||||
</SideBarCollapseItem>
|
||||
</template>
|
||||
</SideBarCollapse>
|
||||
<SideBarDivider />
|
||||
<SideBarCollapse title="tools">
|
||||
<template #icon>
|
||||
<GearIcon />
|
||||
</template>
|
||||
<template #children>
|
||||
<SideBarCollapseItem title="apollon">
|
||||
<CloudIcon />
|
||||
</SideBarCollapseItem>
|
||||
<SideBarCollapseItem title="stats">
|
||||
<GraphIcon />
|
||||
</SideBarCollapseItem>
|
||||
</template>
|
||||
</SideBarCollapse>
|
||||
</nav>
|
||||
</aside>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
const store = useStore()
|
||||
const opened = computed(() => store.getters.isOpened)
|
||||
</script>
|
||||
51
src/components/SideBarCollapse.vue
Normal file
51
src/components/SideBarCollapse.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div class="flex flex-col my-2">
|
||||
<div
|
||||
class="flex cursor-pointer justify-between hover:(bg-red-400 dark:bg-amber-400 dark:text-black) rounded-2xl duration-300 p-3"
|
||||
:class="[{'bg-red-300 dark:bg-amber-300 dark:text-black': collapsed}]"
|
||||
@click.prevent="collapse()"
|
||||
>
|
||||
<div class="flex">
|
||||
<slot name="icon" />
|
||||
<h1 v-if="opened" class="font-semibold ml-2 duration-300">
|
||||
{{ t(`sidebar.${title}`) }}
|
||||
</h1>
|
||||
</div>
|
||||
<div
|
||||
v-if="opened"
|
||||
class="transform duration-300"
|
||||
:class="collapsed ? 'rotate-0' : 'rotate-450'"
|
||||
>
|
||||
<CollapseIcon />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-show="collapsed"
|
||||
class="font-lg"
|
||||
:class="opened ? 'ml-8 border-l-2 border-gray-400 dark:border-gray-600' : 'mt-2'"
|
||||
>
|
||||
<slot name="children" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
const store = useStore()
|
||||
const opened = computed(() => store.getters.isOpened)
|
||||
|
||||
const collapsed = ref(false)
|
||||
const collapse = () => {
|
||||
collapsed.value = !collapsed.value
|
||||
}
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
defineProps({
|
||||
title: {
|
||||
default: 'Title',
|
||||
type: String,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
36
src/components/SideBarCollapseItem.vue
Normal file
36
src/components/SideBarCollapseItem.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<div
|
||||
class="my-2 flex py-1 z-50"
|
||||
:class="{'pl-2': opened}"
|
||||
>
|
||||
<router-link
|
||||
:to="link"
|
||||
class="duration-300 flex hover:(bg-gray-300 dark:bg-gray-700) rounded-2xl cursor-pointer"
|
||||
:class="opened ? 'p-3 w-full' : 'p-3'"
|
||||
>
|
||||
<slot />
|
||||
<h1 v-if="opened" class="font-semibold ml-2">
|
||||
{{ t(`sidebar.${title}`) }}
|
||||
</h1>
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
const store = useStore()
|
||||
const opened = computed(() => store.getters.isOpened)
|
||||
const { t } = useI18n()
|
||||
|
||||
defineProps({
|
||||
title: {
|
||||
default: 'Title',
|
||||
type: String,
|
||||
},
|
||||
link: {
|
||||
default: '/',
|
||||
type: String,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
13
src/components/SideBarDivider.vue
Normal file
13
src/components/SideBarDivider.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div
|
||||
class="border-2 rounded-full border-gray-100 dark:border-gray-800 my-4"
|
||||
:class="{'w-full': !opened}"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
const store = useStore()
|
||||
const opened = computed(() => store.getters.isOpened)
|
||||
</script>
|
||||
33
src/components/SideBarItem.vue
Normal file
33
src/components/SideBarItem.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="flex my-2">
|
||||
<router-link
|
||||
:to="link"
|
||||
class="duration-300 flex hover:(bg-gray-300 dark:bg-gray-700) rounded-2xl cursor-pointer p-3"
|
||||
:class="{'w-full': opened}"
|
||||
>
|
||||
<slot />
|
||||
<h1 v-if="opened" class="font-semibold ml-2">
|
||||
{{ t(`sidebar.${title}`) }}
|
||||
</h1>
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
const store = useStore()
|
||||
const opened = computed(() => store.getters.isOpened)
|
||||
const { t } = useI18n()
|
||||
|
||||
defineProps({
|
||||
title: {
|
||||
default: 'Title',
|
||||
type: String,
|
||||
},
|
||||
link: {
|
||||
default: '/',
|
||||
type: String,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
13
src/components/UpdateButton.vue
Normal file
13
src/components/UpdateButton.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div class="flex">
|
||||
<div class="bg-green-300 hover:bg-green-500 duration-500 cursor-pointer py-2 px-2.5 rounded-lg">
|
||||
<PencilIcon />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'UpdateButton',
|
||||
}
|
||||
</script>
|
||||
14
src/components/icons/ArrowIcon.vue
Normal file
14
src/components/icons/ArrowIcon.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.4em"
|
||||
height="1.4em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M128 20a108 108 0 1 0 108 108A108.122 108.122 0 0 0 128 20zm0 192a84 84 0 1 1 84-84a84.096 84.096 0 0 1-84 84zm48.485-92.485a12 12 0 0 1 0 16.97l-33.941 33.942a12 12 0 0 1-16.97-16.97L139.028 140H88a12 12 0 0 1 0-24h51.03l-13.457-13.456a12 12 0 0 1 16.971-16.97z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
20
src/components/icons/BrushIcon.vue
Normal file
20
src/components/icons/BrushIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M208 20H72a44.05 44.05 0 0 0-44 44v80a20.023 20.023 0 0 0 20 20h50.164l-6.043 42.303A12.045 12.045 0 0 0 92 208a36 36 0 0 0 72 0a12.045 12.045 0 0 0-.12-1.697L157.835 164H208a20.023 20.023 0 0 0 20-20V40a20.023 20.023 0 0 0-20-20zM72 44h84v28a12 12 0 0 0 24 0V44h24v56H52V64a20.023 20.023 0 0 1 20-20zm67.98 164.708a12 12 0 0 1-23.96 0L122.407 164h11.186zM52 140v-16h152v16z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'BrushIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/CloudIcon.vue
Normal file
20
src/components/icons/CloudIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M160 220H72a68 68 0 1 1 7.024-135.64A91.994 91.994 0 1 1 160 220zM70.181 108.037A44 44 0 0 0 72 196h88a68 68 0 1 0-68-68a12 12 0 0 1-24 0a92.006 92.006 0 0 1 2.181-19.963z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CloudIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/CollapseIcon.vue
Normal file
20
src/components/icons/CollapseIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M128 188a11.962 11.962 0 0 1-8.485-3.515l-80-80a12 12 0 0 1 16.97-16.97L128 159.029l71.515-71.514a12 12 0 0 1 16.97 16.97l-80 80A11.962 11.962 0 0 1 128 188z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CollapseIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/CompassIcon.vue
Normal file
20
src/components/icons/CompassIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M128 20a108 108 0 1 0 108 108A108.122 108.122 0 0 0 128 20zm0 192a84 84 0 1 1 84-84a84.096 84.096 0 0 1-84 84zm34.947-134.657l-56.379 22.545a11.999 11.999 0 0 0-6.686 6.685l-22.627 56.569a12 12 0 0 0 15.598 15.598l56.569-22.628a12 12 0 0 0 6.695-6.712l22.437-56.485a12 12 0 0 0-15.607-15.572zm-27.23 58.402l-25.78 10.313l10.318-25.796l25.694-10.274z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CompassIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/CrownIcon.vue
Normal file
20
src/components/icons/CrownIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M241.28 70.454a19.884 19.884 0 0 0-20.883-2.874l-47.239 20.996l-27.675-49.815a20 20 0 0 0-34.966-.001L82.842 88.576l-47.25-21a20 20 0 0 0-27.59 22.85L33.446 198.76a20.066 20.066 0 0 0 24.866 14.682a261.895 261.895 0 0 1 139.33-.013a20.012 20.012 0 0 0 24.858-14.674l25.49-108.318a19.883 19.883 0 0 0-6.71-19.983zM56.81 193.272l-.001-.008l.002.01zm143.276-4.04a286.037 286.037 0 0 0-144.22.013L33.206 92.78l43.231 19.214a19.902 19.902 0 0 0 25.607-8.562L128 56.71l25.957 46.723a19.897 19.897 0 0 0 25.605 8.56l43.22-19.209z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CrownIcon',
|
||||
}
|
||||
</script>
|
||||
36
src/components/icons/CubeIcon.vue
Normal file
36
src/components/icons/CubeIcon.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 24 24"
|
||||
focusable="false"
|
||||
>
|
||||
<g
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M6 17.6l-2-1.1V14" />
|
||||
<path d="M4 10V7.5l2-1.1" />
|
||||
<path d="M10 4.1L12 3l2 1.1" />
|
||||
<path d="M18 6.4l2 1.1V10" />
|
||||
<path d="M20 14v2.5l-2 1.12" />
|
||||
<path d="M14 19.9L12 21l-2-1.1" />
|
||||
<path d="M12 12l2-1.1" />
|
||||
<path d="M18 8.6l2-1.1" />
|
||||
<path d="M12 12v2.5" />
|
||||
<path d="M12 18.5V21" />
|
||||
<path d="M12 12l-2-1.12" />
|
||||
<path d="M6 8.6L4 7.5" />
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CubeIcon',
|
||||
}
|
||||
</script>
|
||||
26
src/components/icons/DegreeHatIcon.vue
Normal file
26
src/components/icons/DegreeHatIcon.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 48 48"
|
||||
focusable="false"
|
||||
>
|
||||
<g
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="4"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M2 17.4L23.022 9l21.022 8.4l-21.022 8.4L2 17.4z" />
|
||||
<path d="M44.044 17.51v9.223" stroke-linecap="round" />
|
||||
<path d="M11.556 21.825v12.442S16.366 39 23.021 39c6.657 0 11.467-4.733 11.467-4.733V21.825" stroke-linecap="round" />
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'DegreeHatIcon',
|
||||
}
|
||||
</script>
|
||||
60
src/components/icons/FlagIcon.vue
Normal file
60
src/components/icons/FlagIcon.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<svg
|
||||
v-if="french"
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 36 36"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
fill="#00247D"
|
||||
d="M0 9.059V13h5.628zM4.664 31H13v-5.837zM23 25.164V31h8.335zM0 23v3.941L5.63 23zM31.337 5H23v5.837zM36 26.942V23h-5.631zM36 13V9.059L30.371 13zM13 5H4.664L13 10.837z"
|
||||
/>
|
||||
<path
|
||||
fill="#CF1B2B"
|
||||
d="M25.14 23l9.712 6.801a3.977 3.977 0 0 0 .99-1.749L28.627 23H25.14zM13 23h-2.141l-9.711 6.8c.521.53 1.189.909 1.938 1.085L13 23.943V23zm10-10h2.141l9.711-6.8a3.988 3.988 0 0 0-1.937-1.085L23 12.057V13zm-12.141 0L1.148 6.2a3.994 3.994 0 0 0-.991 1.749L7.372 13h3.487z"
|
||||
/>
|
||||
<path
|
||||
fill="#EEE"
|
||||
d="M36 21H21v10h2v-5.836L31.335 31H32a3.99 3.99 0 0 0 2.852-1.199L25.14 23h3.487l7.215 5.052c.093-.337.158-.686.158-1.052v-.058L30.369 23H36v-2zM0 21v2h5.63L0 26.941V27c0 1.091.439 2.078 1.148 2.8l9.711-6.8H13v.943l-9.914 6.941c.294.07.598.116.914.116h.664L13 25.163V31h2V21H0zM36 9a3.983 3.983 0 0 0-1.148-2.8L25.141 13H23v-.943l9.915-6.942A4.001 4.001 0 0 0 32 5h-.663L23 10.837V5h-2v10h15v-2h-5.629L36 9.059V9zM13 5v5.837L4.664 5H4a3.985 3.985 0 0 0-2.852 1.2l9.711 6.8H7.372L.157 7.949A3.968 3.968 0 0 0 0 9v.059L5.628 13H0v2h15V5h-2z"
|
||||
/>
|
||||
<path
|
||||
fill="#CF1B2B"
|
||||
d="M21 15V5h-6v10H0v6h15v10h6V21h15v-6z"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
v-else
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 36 36"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
fill="#ED2939"
|
||||
d="M36 27a4 4 0 0 1-4 4h-8V5h8a4 4 0 0 1 4 4v18z"
|
||||
/>
|
||||
<path
|
||||
fill="#002495"
|
||||
d="M4 5a4 4 0 0 0-4 4v18a4 4 0 0 0 4 4h8V5H4z"
|
||||
/>
|
||||
<path
|
||||
fill="#EEE"
|
||||
d="M12 5h12v26H12z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TranslateIcon',
|
||||
props: {
|
||||
french: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/GearIcon.vue
Normal file
20
src/components/icons/GearIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M128 72a56 56 0 1 0 56 56a56.064 56.064 0 0 0-56-56zm0 88a32 32 0 1 1 32-32a32.036 32.036 0 0 1-32 32zm107.602-15.202l-11.608-15.477c.006-.44.009-.881.009-1.32q0-.66-.009-1.324l11.603-15.475a20.037 20.037 0 0 0 3.097-17.966a115.685 115.685 0 0 0-7.824-18.91a20.045 20.045 0 0 0-14.905-10.532l-19.152-2.735q-.46-.474-.927-.94q-.467-.467-.943-.93l-2.738-19.15a20.04 20.04 0 0 0-10.514-14.891a115.71 115.71 0 0 0-18.904-7.84a20.049 20.049 0 0 0-17.986 3.093l-15.477 11.608a99.385 99.385 0 0 0-2.643 0l-15.478-11.605a20.043 20.043 0 0 0-17.965-3.095a115.63 115.63 0 0 0-18.908 7.824a20.041 20.041 0 0 0-10.533 14.905L61.062 59.19q-.475.461-.94.927q-.467.467-.93.943l-19.15 2.738A20.04 20.04 0 0 0 25.15 74.312a115.71 115.71 0 0 0-7.838 18.904a20.044 20.044 0 0 0 3.092 17.986l11.608 15.477c-.006.44-.01.881-.01 1.32q0 .66.01 1.324l-11.603 15.475a20.037 20.037 0 0 0-3.097 17.966a115.685 115.685 0 0 0 7.824 18.91a20.045 20.045 0 0 0 14.905 10.532l19.151 2.735q.462.474.928.94q.467.467.942.93l2.739 19.15a20.04 20.04 0 0 0 10.513 14.892a115.71 115.71 0 0 0 18.905 7.838a20.028 20.028 0 0 0 17.986-3.092l15.477-11.608c.882.012 1.76.013 2.643 0l15.478 11.605a20.044 20.044 0 0 0 17.965 3.095a115.63 115.63 0 0 0 18.908-7.824a20.041 20.041 0 0 0 10.532-14.905l2.736-19.152q.475-.461.94-.927q.467-.467.93-.943l19.15-2.738a20.04 20.04 0 0 0 14.891-10.514a115.71 115.71 0 0 0 7.84-18.904a20.044 20.044 0 0 0-3.093-17.986zm-25.083 23.939l-21.301 3.046a12.002 12.002 0 0 0-7.282 3.92a73.23 73.23 0 0 1-6.233 6.233a12.003 12.003 0 0 0-3.918 7.282l-3.043 21.302a91.672 91.672 0 0 1-11.197 4.633l-17.216-12.908a12.029 12.029 0 0 0-7.919-2.377a73.74 73.74 0 0 1-8.815 0a12.038 12.038 0 0 0-7.92 2.378L98.46 215.158a91.716 91.716 0 0 1-11.194-4.642l-3.046-21.3a11.997 11.997 0 0 0-3.92-7.282a74.047 74.047 0 0 1-3.208-3.02a74.19 74.19 0 0 1-3.023-3.212a12 12 0 0 0-7.284-3.92l-21.302-3.043a91.579 91.579 0 0 1-4.632-11.197l12.907-17.215a11.999 11.999 0 0 0 2.377-7.921a73.472 73.472 0 0 1 0-8.814a12 12 0 0 0-2.378-7.92L40.846 98.456a91.741 91.741 0 0 1 4.641-11.194l21.301-3.046a12.002 12.002 0 0 0 7.282-3.92a73.224 73.224 0 0 1 6.233-6.233a12.003 12.003 0 0 0 3.918-7.282l3.043-21.302a91.672 91.672 0 0 1 11.197-4.633l17.215 12.908a12.02 12.02 0 0 0 7.92 2.377a73.74 73.74 0 0 1 8.815 0a12.018 12.018 0 0 0 7.92-2.378l17.215-12.912a91.716 91.716 0 0 1 11.194 4.642l3.046 21.3a11.997 11.997 0 0 0 3.92 7.282a74.047 74.047 0 0 1 3.208 3.02a74.19 74.19 0 0 1 3.023 3.212a12 12 0 0 0 7.284 3.92l21.301 3.043a91.579 91.579 0 0 1 4.633 11.197l-12.907 17.215a11.999 11.999 0 0 0-2.377 7.921a73.473 73.473 0 0 1 0 8.814a12 12 0 0 0 2.378 7.92l12.911 17.215a91.74 91.74 0 0 1-4.641 11.194z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'GearIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/GlobeIcon.vue
Normal file
20
src/components/icons/GlobeIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M227.107 170.886a11.857 11.857 0 0 0 .642-1.505a107.912 107.912 0 0 0-37.674-129.707a12.15 12.15 0 0 0-1.24-.86A107.944 107.944 0 0 0 39.221 189.43c.031.054.055.111.088.165a12.002 12.002 0 0 0 1.1 1.514a107.84 107.84 0 0 0 153.1 22.69a11.981 11.981 0 0 0 1.73-1.352a108.591 108.591 0 0 0 31.867-41.561zm-42.28 13.568a20.037 20.037 0 0 0-9.08-5.219l-17.995-4.721l1.533-10.412l26.005-10.808l16.393 14.992a84.49 84.49 0 0 1-14.136 18.894zM127.997 44a83.474 83.474 0 0 1 42.99 11.871l.793 16.5l-20.12 23.247l-27.893 3.778l-14.072-11.818a20 20 0 0 0-29.724 4.556l-19.716 30.901a20.097 20.097 0 0 0-3.043 8.79l-3.461 35.036l-.144.087A83.946 83.946 0 0 1 127.997 44zM67.748 186.446l.124-.075a20.093 20.093 0 0 0 9.565-15.155l3.565-36.08l16.748-26.248l11.938 10.026a20.05 20.05 0 0 0 15.545 4.503l31.148-4.219a19.992 19.992 0 0 0 12.437-6.73l22.156-25.6a19.898 19.898 0 0 0 4.428-8.934a83.716 83.716 0 0 1 15.082 65.877l-10.879-9.949a20.073 20.073 0 0 0-21.173-3.709L147.98 142.81a20.1 20.1 0 0 0-12.109 15.554l-2.385 16.197a19.979 19.979 0 0 0 14.71 22.258l19.588 5.14a83.82 83.82 0 0 1-100.036-15.513z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'GlobeIcon',
|
||||
}
|
||||
</script>
|
||||
21
src/components/icons/GraphIcon.vue
Normal file
21
src/components/icons/GraphIcon.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 16 16"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M1.5 1.75a.75.75 0 0 0-1.5 0v12.5c0 .414.336.75.75.75h14.5a.75.75 0 0 0 0-1.5H1.5V1.75zm14.28 2.53a.75.75 0 0 0-1.06-1.06L10 7.94L7.53 5.47a.75.75 0 0 0-1.06 0L3.22 8.72a.75.75 0 0 0 1.06 1.06L7 7.06l2.47 2.47a.75.75 0 0 0 1.06 0l5.25-5.25z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'GraphIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/HomeIcon.vue
Normal file
20
src/components/icons/HomeIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M208 227.999h-.002l-48.007-.006a20.023 20.023 0 0 1-19.997-20v-44.001h-24v44a20.023 20.023 0 0 1-19.998 20L48.003 228a20 20 0 0 1-20.003-20v-92.46a20.036 20.036 0 0 1 6.547-14.8l79.992-72.733a19.922 19.922 0 0 1 26.908-.002l80.007 72.736a20.046 20.046 0 0 1 6.546 14.8V208a20 20 0 0 1-20 20zm-44.006-24.006L204 204v-86.69L127.994 48.21L52 117.308v86.69l39.994-.005v-44.001a20.023 20.023 0 0 1 20-20h32a20.023 20.023 0 0 1 20 20z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HomeIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/LinkIcon.vue
Normal file
20
src/components/icons/LinkIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M85.568 153.446l67.883-67.882a12 12 0 1 1 16.97 16.971l-67.882 67.882a12 12 0 1 1-16.971-16.97zm50.91 16.979l-28.284 28.284a36 36 0 0 1-50.912-50.911l28.284-28.284a12 12 0 0 0-16.97-16.971L40.31 130.827a60 60 0 0 0 84.854 84.853l28.284-28.284a12 12 0 0 0-16.971-16.971zm79.201-130.113a60.068 60.068 0 0 0-84.853 0l-28.284 28.285a12 12 0 0 0 16.97 16.97l28.284-28.284a36 36 0 0 1 50.913 50.911l-28.285 28.285a12 12 0 0 0 16.971 16.97l28.284-28.284a60 60 0 0 0 0-84.853z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'LinkIco',
|
||||
}
|
||||
</script>
|
||||
19
src/components/icons/MediaIcon.vue
Normal file
19
src/components/icons/MediaIcon.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
>
|
||||
<path
|
||||
d="M88.687 103.314A16 16 0 1 1 116 92v.005a16.001 16.001 0 0 1-27.314 11.31zM228 48v160a20.022 20.022 0 0 1-20 20H48a20.022 20.022 0 0 1-20-20V48a20.022 20.022 0 0 1 20-20h160a20.022 20.022 0 0 1 20 20zm-24 116.97l-35.999-36l-41.858 41.86a20.025 20.025 0 0 1-28.285 0L80 152.97l-28 28V204h152zM204 52H52v95.03l13.858-13.858a20.023 20.023 0 0 1 28.285 0L112 151.03l41.857-41.858a20.025 20.025 0 0 1 28.285 0L204 131.029z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MediaIcon',
|
||||
}
|
||||
</script>
|
||||
21
src/components/icons/MoonIcon.vue
Normal file
21
src/components/icons/MoonIcon.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 16 16"
|
||||
focusable="false"
|
||||
>
|
||||
<g fill="currentColor">
|
||||
<path
|
||||
d="M6 .278a.768.768 0 0 1 .08.858a7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277c.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316a.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71C0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MoonIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/NewspaperIcon.vue
Normal file
20
src/components/icons/NewspaperIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M92 108a12 12 0 0 1 12-12h72a12 12 0 0 1 0 24h-72a12 12 0 0 1-12-12zm12 52h72a12 12 0 0 0 0-24h-72a12 12 0 0 0 0 24zm132-96v120a28.031 28.031 0 0 1-28 28H36a32.037 32.037 0 0 1-32-32V88a12 12 0 0 1 24 0v92a8 8 0 0 0 16 0V64a20.022 20.022 0 0 1 20-20h152a20.022 20.022 0 0 1 20 20zm-24 4H68v112a31.927 31.927 0 0 1-1.013 8H208a4.004 4.004 0 0 0 4-4z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'NewspaperIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/PenIcon.vue
Normal file
20
src/components/icons/PenIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M234.834 89.861l-68.686-68.686a20.023 20.023 0 0 0-28.284 0l-24.505 24.504l-57.246 21.467A20.061 20.061 0 0 0 43.41 82.585L20.169 222.03c-.015.09-.016.18-.028.27a12.057 12.057 0 0 0-.12 1.385c-.008.307-.002.612.013.919c.007.132.009.266.02.398a12.011 12.011 0 0 0 .503 2.582c.03.097.068.19.101.287c.11.322.232.641.37.956c.05.115.104.228.158.342q.208.435.453.855c.067.114.131.228.201.34c.174.278.364.548.563.814c.074.098.142.2.219.297a12.089 12.089 0 0 0 .874.985c.009.01.016.02.025.028a11.916 11.916 0 0 0 .894.808c.265.217.54.414.818.605c.044.03.085.066.13.096a11.91 11.91 0 0 0 3.145 1.483l.026.01c.329.098.662.178.996.248c.05.011.097.026.146.036c.309.06.62.102.933.139c.076.008.151.025.228.032q.575.057 1.153.057h.019c.355 0 .711-.018 1.068-.05c.126-.012.252-.032.378-.047c.175-.021.35-.036.524-.065l139.445-23.24a20.056 20.056 0 0 0 15.439-12.705l21.466-57.245l24.505-24.504a20.023 20.023 0 0 0 0-28.285zm-67.632 99.445L66.965 206.01l33.524-33.529a36.014 36.014 0 1 0-16.97-16.97l-33.52 33.524L66.704 88.808l50.28-18.856l69.073 69.072zM104 140a12 12 0 1 1 12 12a12.013 12.013 0 0 1-12-12zm96.006-20.968l-63.03-63.03l15.03-15.028l63.03 63.029z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'PenIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/PencilIcon.vue
Normal file
20
src/components/icons/PencilIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M226.829 73.858l-44.687-44.686a20 20 0 0 0-28.284 0l-26.343 26.342l-.001.002l-93.655 93.655A19.866 19.866 0 0 0 28 163.313V208a20.023 20.023 0 0 0 20 20h48a12 12 0 0 0 8.485-3.515L226.83 102.142a20.023 20.023 0 0 0 0-28.284zM91.029 204H52v-39.03l84-84L175.03 120zM192 103.03L152.97 64L168 48.97L207.03 88z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'PencilIcon',
|
||||
}
|
||||
</script>
|
||||
31
src/components/icons/PresentationIcon.vue
Normal file
31
src/components/icons/PresentationIcon.vue
Normal file
@@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 24 24"
|
||||
focusable="false"
|
||||
>
|
||||
<g
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M9 12V8" />
|
||||
<path d="M15 12v-2" />
|
||||
<path d="M12 12v-1" />
|
||||
<path d="M3 4h18" />
|
||||
<path d="M4 4v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V4" />
|
||||
<path d="M12 16v4" />
|
||||
<path d="M9 20h6" />
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'PresentationIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/StarIcon.vue
Normal file
20
src/components/icons/StarIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M187.264 235.988a20.215 20.215 0 0 1-10.84-3.165L128 202.143l-44.86 28.421a21.78 21.78 0 0 1-24.569-.772a22.35 22.35 0 0 1-8.527-23.74l13.015-51.2l-43.614-36.3a20.639 20.639 0 0 1-6.409-22.372a20.34 20.34 0 0 1 18.068-14.13l56.749-3.683l21.217-53.428a20.317 20.317 0 0 1 37.86 0l21.217 53.428l56.749 3.683a20.34 20.34 0 0 1 18.068 14.13a20.638 20.638 0 0 1-6.41 22.372l-43.613 36.3l14.074 55.362a20.615 20.615 0 0 1-7.871 21.895a20.2 20.2 0 0 1-11.88 3.879zm2.005-23.438zM128 177.469a20.237 20.237 0 0 1 10.833 3.127l42.78 27.103l-12.43-48.894a20.834 20.834 0 0 1 6.792-21.056l38.812-32.305l-50.51-3.278a20.517 20.517 0 0 1-17.624-12.898L128 42.297L109.346 89.27a20.515 20.515 0 0 1-17.622 12.896l-50.511 3.278l38.813 32.305a20.833 20.833 0 0 1 6.791 21.055L74.39 207.698l42.778-27.102A20.235 20.235 0 0 1 128 177.469zm-2.01 23.4l.002.003l-.003-.003z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'StarIcon',
|
||||
}
|
||||
</script>
|
||||
52
src/components/icons/SunIcon.vue
Normal file
52
src/components/icons/SunIcon.vue
Normal file
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 512 512"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M256 118a22 22 0 0 1-22-22V48a22 22 0 0 1 44 0v48a22 22 0 0 1-22 22z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M256 486a22 22 0 0 1-22-22v-48a22 22 0 0 1 44 0v48a22 22 0 0 1-22 22z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M369.14 164.86a22 22 0 0 1-15.56-37.55l33.94-33.94a22 22 0 0 1 31.11 31.11l-33.94 33.94a21.93 21.93 0 0 1-15.55 6.44z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M108.92 425.08a22 22 0 0 1-15.55-37.56l33.94-33.94a22 22 0 1 1 31.11 31.11l-33.94 33.94a21.94 21.94 0 0 1-15.56 6.45z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M464 278h-48a22 22 0 0 1 0-44h48a22 22 0 0 1 0 44z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M96 278H48a22 22 0 0 1 0-44h48a22 22 0 0 1 0 44z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M403.08 425.08a21.94 21.94 0 0 1-15.56-6.45l-33.94-33.94a22 22 0 0 1 31.11-31.11l33.94 33.94a22 22 0 0 1-15.55 37.56z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M142.86 164.86a21.89 21.89 0 0 1-15.55-6.44l-33.94-33.94a22 22 0 0 1 31.11-31.11l33.94 33.94a22 22 0 0 1-15.56 37.55z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M256 358a102 102 0 1 1 102-102a102.12 102.12 0 0 1-102 102z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SunIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/TagIcon.vue
Normal file
20
src/components/icons/TagIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M242.828 124.034L138.376 19.582a19.956 19.956 0 0 0-18.064-5.47L39.656 30.243a11.998 11.998 0 0 0-9.413 9.413l-16.13 80.656a19.96 19.96 0 0 0 5.469 18.064l104.451 104.451a19.999 19.999 0 0 0 28.285.001l90.51-90.509a19.999 19.999 0 0 0 0-28.285zM138.177 223.03L38.065 122.92l14.143-70.711l70.711-14.143l100.11 100.112zM100 84a16 16 0 1 1-16-16a16.018 16.018 0 0 1 16 16z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TagIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/TranslateIcon.vue
Normal file
20
src/components/icons/TranslateIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M242.715 210.634l-56-112a12 12 0 0 0-21.465 0l-20.504 41.006a84.114 84.114 0 0 1-38.76-13.44A107.568 107.568 0 0 0 131.312 68h20.67a12 12 0 0 0 0-24h-52V32a12 12 0 0 0-24 0v12h-52a12 12 0 0 0 0 24h83.13a83.665 83.665 0 0 1-19.142 42.332A83.593 83.593 0 0 1 75.6 90.992a12 12 0 0 0-21.809 10.019a107.462 107.462 0 0 0 16.2 25.216A83.49 83.49 0 0 1 23.982 140a12 12 0 1 0 0 24a107.423 107.423 0 0 0 64.031-21.085a108.427 108.427 0 0 0 45.386 19.42l-24.15 48.299a12 12 0 1 0 21.466 10.732L143.4 196h65.167l12.684 25.366a12 12 0 1 0 21.465-10.732zM155.4 172l20.583-41.167L196.566 172z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TranslateIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/TrashIcon.vue
Normal file
20
src/components/icons/TrashIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M215.996 48H180V36a28.031 28.031 0 0 0-28-28h-48a28.031 28.031 0 0 0-28 28v12H39.996a12 12 0 0 0 0 24h4v136a20.023 20.023 0 0 0 20 20h128a20.023 20.023 0 0 0 20-20V72h4a12 12 0 0 0 0-24zM100 36a4.005 4.005 0 0 1 4-4h48a4.005 4.005 0 0 1 4 4v12h-56zm87.996 168h-120V72h120zM116 104v64a12 12 0 0 1-24 0v-64a12 12 0 0 1 24 0zm48 0v64a12 12 0 0 1-24 0v-64a12 12 0 0 1 24 0z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TrashIcon',
|
||||
}
|
||||
</script>
|
||||
20
src/components/icons/UsersIcon.vue
Normal file
20
src/components/icons/UsersIcon.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<svg
|
||||
class="inline"
|
||||
width="1.5em"
|
||||
height="1.5em"
|
||||
viewBox="0 0 256 256"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
d="M129.21 156.914a64 64 0 1 0-82.42 0a100.18 100.18 0 0 0-40.606 33.574a12 12 0 1 0 19.624 13.817a76.017 76.017 0 0 1 124.38-.005a12 12 0 1 0 19.624-13.818a100.179 100.179 0 0 0-40.602-33.568zM48 108a40 40 0 1 1 40 40a40.045 40.045 0 0 1-40-40zm200.432 99.203a11.998 11.998 0 0 1-16.721-2.903a76.164 76.164 0 0 0-62.189-32.3a12 12 0 0 1 0-24a40 40 0 1 0-10.86-78.511a12 12 0 0 1-6.499-23.104a63.978 63.978 0 0 1 58.568 110.53a100.18 100.18 0 0 1 40.603 33.567a12 12 0 0 1-2.902 16.72z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'UsersIcon',
|
||||
}
|
||||
</script>
|
||||
13
src/layouts/404.vue
Normal file
13
src/layouts/404.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const router = useRouter()
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="px-4 py-10 text-center text-teal-700 dark:text-gray-200">
|
||||
ERROR
|
||||
</main>
|
||||
</template>
|
||||
3
src/layouts/auth.vue
Normal file
3
src/layouts/auth.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<router-view />
|
||||
</template>
|
||||
22
src/layouts/default.vue
Normal file
22
src/layouts/default.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<main class="flex">
|
||||
<SideBar />
|
||||
<div
|
||||
class="w-full h-full duration-300"
|
||||
:class="opened ? 'ml-64' : 'ml-20'"
|
||||
>
|
||||
<Header />
|
||||
<div class="mt-16 p-4">
|
||||
<router-view />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
const store = useStore()
|
||||
const opened = computed(() => store.getters.isOpened)
|
||||
</script>
|
||||
60
src/logic/auth.ts
Normal file
60
src/logic/auth.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { store } from '~/store'
|
||||
import { useAxios } from '~/logic/axios'
|
||||
|
||||
export interface User {
|
||||
id: number
|
||||
username: string
|
||||
email: string
|
||||
}
|
||||
|
||||
interface Credentials {
|
||||
email: string
|
||||
password: string
|
||||
}
|
||||
|
||||
interface Auth {
|
||||
readonly isAuthenticated: Boolean
|
||||
readonly user: User
|
||||
readonly login: (credentials: Credentials) => Promise<void>
|
||||
readonly logout: () => Promise<void>
|
||||
}
|
||||
|
||||
export const useAuth = (): Auth => {
|
||||
const axios = useAxios()
|
||||
const router = useRouter()
|
||||
const user = computed(() => store.getters.getUser)
|
||||
const isAuthenticated = computed(() => store.getters.isAuthenticated)
|
||||
|
||||
const login = async(
|
||||
credentials: Credentials,
|
||||
) => {
|
||||
const response = await axios.post('/auth/web/login', {
|
||||
email: credentials.email,
|
||||
password: credentials.password,
|
||||
})
|
||||
if (response.status === 200) {
|
||||
store.commit('SET_AUTHENTICATED', true)
|
||||
store.commit('SET_USER', {
|
||||
id: response.data.user.id,
|
||||
email: response.data.user.email,
|
||||
username: response.data.user.username,
|
||||
})
|
||||
await router.push({ name: 'index' })
|
||||
}
|
||||
}
|
||||
const logout = async() => {
|
||||
const response = await axios.post('/auth/web/logout')
|
||||
if (response.status === 200) {
|
||||
await store.commit('SET_AUTHENTICATED', false)
|
||||
await store.commit('RESET_USER')
|
||||
await router.push({ name: 'login' })
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
login,
|
||||
logout,
|
||||
isAuthenticated: isAuthenticated.value,
|
||||
user: user.value,
|
||||
}
|
||||
}
|
||||
10
src/logic/axios.ts
Normal file
10
src/logic/axios.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import axios from 'axios'
|
||||
|
||||
const instance = axios.create({
|
||||
baseURL: String(import.meta.env.VITE_ENV) === 'development' ? String(import.meta.env.VITE_API_URL_DEV) : String(import.meta.env.VITE_API_URL),
|
||||
withCredentials: true,
|
||||
})
|
||||
|
||||
export const useAxios = () => {
|
||||
return instance
|
||||
}
|
||||
2
src/logic/dark.ts
Normal file
2
src/logic/dark.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export const isDark = useDark()
|
||||
export const toggleDark = useToggle(isDark)
|
||||
1
src/logic/index.ts
Normal file
1
src/logic/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './dark'
|
||||
27
src/main.ts
Normal file
27
src/main.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
// register vue composition api globally
|
||||
import 'vue-global-api'
|
||||
import { ViteSSG } from 'vite-ssg'
|
||||
import generatedRoutes from 'virtual:generated-pages'
|
||||
import { setupLayouts } from 'virtual:generated-layouts'
|
||||
import App from './App.vue'
|
||||
|
||||
// windicss layers
|
||||
import 'virtual:windi-base.css'
|
||||
import 'virtual:windi-components.css'
|
||||
// your custom styles here
|
||||
import './styles/main.css'
|
||||
// windicss utilities should be the last style import
|
||||
import 'virtual:windi-utilities.css'
|
||||
// windicss devtools support (dev only)
|
||||
import 'virtual:windi-devtools'
|
||||
|
||||
const routes = setupLayouts(generatedRoutes)
|
||||
|
||||
export const createApp = ViteSSG(
|
||||
App,
|
||||
{ routes },
|
||||
(ctx) => {
|
||||
// install all modules under `modules/`
|
||||
Object.values(import.meta.globEager('./modules/*.ts')).map(i => i.install?.(ctx))
|
||||
},
|
||||
)
|
||||
11
src/modules/README.md
Normal file
11
src/modules/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
## Modules
|
||||
|
||||
A custom user module system. Place a `.ts` file with the following template, it will be installed automatically.
|
||||
|
||||
```ts
|
||||
import { UserModule } from '~/types'
|
||||
|
||||
export const install: UserModule = ({ app, router, isClient }) => {
|
||||
// do something
|
||||
}
|
||||
```
|
||||
24
src/modules/auth.ts
Normal file
24
src/modules/auth.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { store } from '~/store'
|
||||
import { useAuth } from '~/logic/auth'
|
||||
import { UserModule } from '~/types'
|
||||
|
||||
export const install: UserModule = ({ isClient, router }) => {
|
||||
if (isClient) {
|
||||
router.beforeEach(async(from, to, next) => {
|
||||
const { isAuthenticated, user } = useAuth()
|
||||
|
||||
if (user === null)
|
||||
await store.dispatch('FETCH_USER')
|
||||
|
||||
// redirect to login page if not connected
|
||||
if (from.meta.auth && !isAuthenticated)
|
||||
next({ name: 'login' })
|
||||
|
||||
// redirect to home page if connected
|
||||
else if (from.meta.guest && isAuthenticated)
|
||||
next({ name: 'index' })
|
||||
|
||||
else next()
|
||||
})
|
||||
}
|
||||
}
|
||||
21
src/modules/i18n.ts
Normal file
21
src/modules/i18n.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import { UserModule } from '~/types'
|
||||
|
||||
const messages = Object.fromEntries(
|
||||
Object.entries(
|
||||
import.meta.globEager('../../locales/*.json'))
|
||||
.map(([key, value]) => {
|
||||
return [key.slice(14, -5), value.default]
|
||||
}),
|
||||
)
|
||||
|
||||
export const install: UserModule = ({ app }) => {
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
messages,
|
||||
fallbackLocale: 'en',
|
||||
})
|
||||
|
||||
app.use(i18n)
|
||||
}
|
||||
9
src/modules/nprogress.ts
Normal file
9
src/modules/nprogress.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import NProgress from 'nprogress'
|
||||
import { UserModule } from '~/types'
|
||||
|
||||
export const install: UserModule = ({ isClient, router }) => {
|
||||
if (isClient) {
|
||||
router.beforeEach(() => { NProgress.start() })
|
||||
router.afterEach(() => { NProgress.done() })
|
||||
}
|
||||
}
|
||||
12
src/modules/pwa.ts
Normal file
12
src/modules/pwa.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { UserModule } from '~/types'
|
||||
|
||||
// https://github.com/antfu/vite-plugin-pwa#automatic-reload-when-new-content-available
|
||||
export const install: UserModule = ({ isClient, router }) => {
|
||||
if (!isClient)
|
||||
return
|
||||
|
||||
router.isReady().then(async() => {
|
||||
const { registerSW } = await import('virtual:pwa-register')
|
||||
registerSW({ immediate: true })
|
||||
})
|
||||
}
|
||||
7
src/modules/store.ts
Normal file
7
src/modules/store.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { UserModule } from '~/types'
|
||||
import { store } from '~/store'
|
||||
|
||||
export const install: UserModule = ({ isClient, app }) => {
|
||||
if (isClient)
|
||||
app.use(store)
|
||||
}
|
||||
15
src/pages/index.vue
Normal file
15
src/pages/index.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<div>
|
||||
{{ t('hello') }} <br />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<route lang="yaml">
|
||||
meta:
|
||||
layout: default
|
||||
auth: true
|
||||
</route>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
100
src/pages/login.vue
Normal file
100
src/pages/login.vue
Normal file
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<main class="p-12 h-screen w-screen bg-gradient-to-r from-amber-400 to-pink-400 dark:(bg-gradient-to-r from-blue-900 to-purple-900) flex items-center justify-center">
|
||||
<div class="relative bg-white dark:bg-gray-900 p-4 rounded-xl flex flex-col justify-between w-full lg:w-1/3">
|
||||
<div class="absolute top-5 left-5 flex">
|
||||
<ColorModeButton class="mr-2" />
|
||||
<LanguageButton />
|
||||
</div>
|
||||
<div class="mb-8">
|
||||
<div class="text-center mt-8 mb-12">
|
||||
<Logo />
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<form class="w-full">
|
||||
<div class="w-full mb-8">
|
||||
<input
|
||||
id="email"
|
||||
v-model="form.email"
|
||||
required
|
||||
:placeholder="t('login.form.email')"
|
||||
type="text"
|
||||
class="w-full py-2 px-4 border-gray-200 focus:bg-gray-100 duration-300 dark:(border-gray-800 bg-gray-900 focus:bg-gray-800) border-2 rounded-lg"
|
||||
/>
|
||||
</div>
|
||||
<div class=" w-full">
|
||||
<input
|
||||
id="password"
|
||||
v-model="form.password"
|
||||
required
|
||||
:placeholder="t('login.form.password')"
|
||||
type="password"
|
||||
autocomplete="suggested"
|
||||
class="w-full py-2 px-4 border-gray-200 focus:bg-gray-100 duration-300 dark:(border-gray-800 bg-gray-900 focus:bg-gray-800) border-2 rounded-lg"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex justify-between my-2">
|
||||
<div class="font-thin text-sm duration-300" :class="error ? 'text-red-500': 'text-transparent'">
|
||||
{{ t('login.credentials') }}
|
||||
</div>
|
||||
<div class="text-sm duration-300 cursor-pointer border-b-2 border-gray-200 hover:(border-red-400 text-red-400 dark:text-amber-400 dark:border-amber-400) text-gray-400">
|
||||
{{ t('login.forget') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-8 flex justify-center">
|
||||
<button
|
||||
class="w-full font-bold px-8 py-2 border-2 rounded-lg border-red-400 dark:border-amber-400 text-red-400 dark:text-amber-400 hover:(bg-red-400 dark:bg-amber-400 text-white) hover:dark:text-black duration-300 cursor-pointer"
|
||||
@click.prevent="handleLogin()"
|
||||
>
|
||||
{{ t('login.form.login') }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="mt-2 flex justify-center">
|
||||
<div class="text-sm cursor-pointer">
|
||||
{{ t('login.no_account') }} <span class="duration-300 border-b-2 border-gray-200 hover:(border-red-400 text-red-400 dark:text-amber-400 dark:border-amber-400) text-gray-400">{{ t('login.ask') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-center flex-col items-center">
|
||||
<p class="block text-xs text-gray-700 dark:text-gray-300">
|
||||
{{ t('login.secure') }}
|
||||
</p>
|
||||
<p class="text-xs text-gray-700 dark:text-gray-300">
|
||||
{{ t('login.credits') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useStore } from 'vuex'
|
||||
import { useAuth } from '~/logic/auth'
|
||||
|
||||
const store = useStore()
|
||||
const { t } = useI18n()
|
||||
|
||||
const form = ref({ email: '', password: '' })
|
||||
const error = ref(false)
|
||||
const { login } = useAuth()
|
||||
const handleLogin = () => {
|
||||
login({
|
||||
email: form.value.email,
|
||||
password: form.value.password,
|
||||
}).catch(() => {
|
||||
form.value.password = ''
|
||||
error.value = true
|
||||
setTimeout(() => error.value = false, 7000)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<route lang="yaml">
|
||||
meta:
|
||||
layout: auth
|
||||
guest: true
|
||||
</route>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
58
src/pages/users/index.vue
Normal file
58
src/pages/users/index.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<main class="mb-8 duration-300 rounded-xl bg-white shadow-white dark:(bg-dark-900 shadow-black) h-100 p-4">
|
||||
<PageTitle title="Users">
|
||||
<UsersIcon />
|
||||
</PageTitle>
|
||||
<div class="w-full">
|
||||
<div class="table empty-cells-hidden w-full">
|
||||
<div class="table-caption">Liste des utilisateurs</div>
|
||||
<div class="table-header-group">
|
||||
<div class="table-row">
|
||||
<div class="table-cell">Id</div>
|
||||
<div class="table-cell">Nom</div>
|
||||
<div class="table-cell">Email</div>
|
||||
<div class="table-cell">Actions</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-row-group">
|
||||
<div class="table-row" v-for="user in users" :key="user.id">
|
||||
<div class="table-cell">{{user.id}}</div>
|
||||
<div class="table-cell">{{user.username}}</div>
|
||||
<div class="table-cell">{{user.email}}</div>
|
||||
<div class="table-cell">
|
||||
<div class="flex">
|
||||
<DeleteButton class="mr-2" />
|
||||
<UpdateButton />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-footer-group">
|
||||
total : {{ users.length }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<route lang="yaml">
|
||||
meta:
|
||||
layout: default
|
||||
auth: true
|
||||
</route>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useAxios } from '~/logic/axios'
|
||||
|
||||
const axios = useAxios()
|
||||
const users = ref<Array<any>>([])
|
||||
|
||||
onMounted(async() => {
|
||||
const response = await axios.get('/users')
|
||||
if (response.status === 200) {
|
||||
response.data.users.forEach((user: any) => {
|
||||
return users.value.push(user)
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
18
src/shims.d.ts
vendored
Normal file
18
src/shims.d.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
declare interface Window {
|
||||
// extend the window
|
||||
}
|
||||
|
||||
// with vite-plugin-md, markdowns can be treat as Vue components
|
||||
declare module '*.md' {
|
||||
import { ComponentOptions } from 'vue'
|
||||
const component: ComponentOptions
|
||||
export default component
|
||||
}
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
import { Store } from 'vuex'
|
||||
|
||||
interface ComponentCustomProperties {
|
||||
$store: Store
|
||||
}
|
||||
}
|
||||
10
src/store/index.ts
Normal file
10
src/store/index.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { createStore } from 'vuex'
|
||||
import auth from '~/store/modules/auth'
|
||||
import sidebar from '~/store/modules/sidebar'
|
||||
|
||||
export const store = createStore({
|
||||
modules: {
|
||||
auth,
|
||||
sidebar,
|
||||
},
|
||||
})
|
||||
54
src/store/modules/auth.ts
Normal file
54
src/store/modules/auth.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { Module } from 'vuex'
|
||||
import { User } from '~/logic/auth'
|
||||
import { useAxios } from '~/logic/axios'
|
||||
const axios = useAxios()
|
||||
|
||||
const authModule: Module<any, any> = {
|
||||
state: {
|
||||
user: null,
|
||||
authenticated: false,
|
||||
},
|
||||
getters: {
|
||||
getUser(state: any) {
|
||||
return state.user
|
||||
},
|
||||
isAuthenticated(state: any) {
|
||||
return state.authenticated
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
SET_USER(state: any, user: User) {
|
||||
state.user = user
|
||||
},
|
||||
RESET_USER(state: any) {
|
||||
state.user = null
|
||||
},
|
||||
SET_AUTHENTICATED(state: any, value: boolean) {
|
||||
state.authenticated = value
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
async FETCH_USER({ commit, state }) {
|
||||
let user: User | null = state.user
|
||||
if (!user) {
|
||||
try {
|
||||
const response = await axios.get('/auth/me')
|
||||
if (response.status === 200) {
|
||||
user = {
|
||||
id: response.data.user.id,
|
||||
username: response.data.user.username,
|
||||
email: response.data.user.email,
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
user = null
|
||||
}
|
||||
}
|
||||
commit('SET_USER', user)
|
||||
commit('SET_AUTHENTICATED', true)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default authModule
|
||||
20
src/store/modules/sidebar.ts
Normal file
20
src/store/modules/sidebar.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { Module } from 'vuex'
|
||||
|
||||
const sidebarModule: Module<any, any> = {
|
||||
state: {
|
||||
opened: true,
|
||||
},
|
||||
getters: {
|
||||
isOpened(state: any) {
|
||||
return state.opened
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
SET_OPENED(state: any, value: boolean) {
|
||||
state.opened = value
|
||||
},
|
||||
},
|
||||
actions: {},
|
||||
}
|
||||
|
||||
export default sidebarModule
|
||||
33
src/styles/main.css
Executable file
33
src/styles/main.css
Executable file
@@ -0,0 +1,33 @@
|
||||
@import './markdown.css';
|
||||
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
@apply duration-300 bg-gray-100;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
@apply bg-dark-800 text-white;
|
||||
}
|
||||
|
||||
#nprogress {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#nprogress .bar {
|
||||
@apply bg-teal-600 opacity-75;
|
||||
|
||||
position: fixed;
|
||||
z-index: 1031;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
}
|
||||
54
src/styles/markdown.css
Normal file
54
src/styles/markdown.css
Normal file
@@ -0,0 +1,54 @@
|
||||
/* https://github.com/antfu/prism-theme-vars */
|
||||
@import 'prism-theme-vars/base.css';
|
||||
|
||||
.prose {
|
||||
--prism-font-family: 'Input Mono', monospace;
|
||||
}
|
||||
|
||||
html:not(.dark) .prose {
|
||||
--prism-foreground: #393a34;
|
||||
--prism-background: #fbfbfb;
|
||||
--prism-comment: #a0ada0;
|
||||
--prism-string: #b56959;
|
||||
--prism-literal: #2f8a89;
|
||||
--prism-number: #296aa3;
|
||||
--prism-keyword: #1c6b48;
|
||||
--prism-function: #6c7834;
|
||||
--prism-boolean: #1c6b48;
|
||||
--prism-constant: #a65e2b;
|
||||
--prism-deleted: #a14f55;
|
||||
--prism-class: #2993a3;
|
||||
--prism-builtin: #ab5959;
|
||||
--prism-property: #b58451;
|
||||
--prism-namespace: #b05a78;
|
||||
--prism-punctuation: #8e8f8b;
|
||||
--prism-decorator: #bd8f8f;
|
||||
--prism-regex: #ab5e3f;
|
||||
--prism-json-property: #698c96;
|
||||
}
|
||||
|
||||
html.dark .prose {
|
||||
--prism-foreground: #d4cfbf;
|
||||
--prism-background: #151515;
|
||||
--prism-comment: #758575;
|
||||
--prism-string: #d48372;
|
||||
--prism-literal: #429988;
|
||||
--prism-keyword: #4d9375;
|
||||
--prism-boolean: #1c6b48;
|
||||
--prism-number: #6394bf;
|
||||
--prism-variable: #c2b36e;
|
||||
--prism-function: #a1b567;
|
||||
--prism-deleted: #a14f55;
|
||||
--prism-class: #54b1bf;
|
||||
--prism-builtin: #e0a569;
|
||||
--prism-property: #dd8e6e;
|
||||
--prism-namespace: #db889a;
|
||||
--prism-punctuation: #858585;
|
||||
--prism-decorator: #bd8f8f;
|
||||
--prism-regex: #ab5e3f;
|
||||
--prism-json-property: #6b8b9e;
|
||||
--prism-line-number: #888888;
|
||||
--prism-line-number-gutter: #eeeeee;
|
||||
--prism-line-highlight-background: #444444;
|
||||
--prism-selection-background: #444444;
|
||||
}
|
||||
3
src/types.ts
Normal file
3
src/types.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { ViteSSGContext } from 'vite-ssg'
|
||||
|
||||
export type UserModule = (ctx: ViteSSGContext) => void
|
||||
27
tsconfig.json
Normal file
27
tsconfig.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"module": "ESNext",
|
||||
"target": "es2016",
|
||||
"lib": ["DOM", "ESNext"],
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"incremental": false,
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"noUnusedLocals": true,
|
||||
"strictNullChecks": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"types": [
|
||||
"vite/client",
|
||||
"vite-plugin-pages/client",
|
||||
"vite-plugin-vue-layouts/client",
|
||||
"@types/axios",
|
||||
],
|
||||
"paths": {
|
||||
"~/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["dist", "node_modules"]
|
||||
}
|
||||
158
vite.config.ts
Normal file
158
vite.config.ts
Normal file
@@ -0,0 +1,158 @@
|
||||
import path from 'path'
|
||||
import { defineConfig } from 'vite'
|
||||
import Vue from '@vitejs/plugin-vue'
|
||||
import Pages from 'vite-plugin-pages'
|
||||
import Layouts from 'vite-plugin-vue-layouts'
|
||||
import Icons from 'unplugin-icons/vite'
|
||||
import IconsResolver from 'unplugin-icons/resolver'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import Markdown from 'vite-plugin-md'
|
||||
import WindiCSS from 'vite-plugin-windicss'
|
||||
import { VitePWA } from 'vite-plugin-pwa'
|
||||
import VueI18n from '@intlify/vite-plugin-vue-i18n'
|
||||
import Prism from 'markdown-it-prism'
|
||||
import LinkAttributes from 'markdown-it-link-attributes'
|
||||
|
||||
const markdownWrapperClasses = 'prose prose-sm m-auto text-left'
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
'~/': `${path.resolve(__dirname, 'src')}/`,
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
Vue({
|
||||
include: [/\.vue$/, /\.md$/],
|
||||
}),
|
||||
|
||||
// https://github.com/hannoeru/vite-plugin-pages
|
||||
Pages({
|
||||
extensions: ['vue', 'md'],
|
||||
}),
|
||||
|
||||
// https://github.com/JohnCampionJr/vite-plugin-vue-layouts
|
||||
Layouts(),
|
||||
|
||||
// https://github.com/antfu/unplugin-auto-import
|
||||
AutoImport({
|
||||
imports: [
|
||||
'vue',
|
||||
'vue-router',
|
||||
'vue-i18n',
|
||||
'@vueuse/head',
|
||||
'@vueuse/core',
|
||||
],
|
||||
dts: true,
|
||||
}),
|
||||
|
||||
// https://github.com/antfu/unplugin-vue-components
|
||||
Components({
|
||||
// allow auto load markdown components under `./src/components/`
|
||||
extensions: ['vue', 'md'],
|
||||
|
||||
dts: true,
|
||||
|
||||
deep: true,
|
||||
|
||||
// allow auto import and register components used in markdown
|
||||
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
|
||||
|
||||
// custom resolvers
|
||||
resolvers: [
|
||||
// auto import icons
|
||||
// https://github.com/antfu/unplugin-icons
|
||||
IconsResolver({
|
||||
componentPrefix: '',
|
||||
// enabledCollections: ['carbon']
|
||||
}),
|
||||
],
|
||||
}),
|
||||
|
||||
// https://github.com/antfu/unplugin-icons
|
||||
Icons(),
|
||||
|
||||
// https://github.com/antfu/vite-plugin-windicss
|
||||
WindiCSS({
|
||||
safelist: markdownWrapperClasses,
|
||||
}),
|
||||
|
||||
// https://github.com/antfu/vite-plugin-md
|
||||
// Don't need this? Try vitesse-lite: https://github.com/antfu/vitesse-lite
|
||||
Markdown({
|
||||
wrapperClasses: markdownWrapperClasses,
|
||||
headEnabled: true,
|
||||
markdownItSetup(md) {
|
||||
// https://prismjs.com/
|
||||
md.use(Prism)
|
||||
md.use(LinkAttributes, {
|
||||
pattern: /^https?:\/\//,
|
||||
attrs: {
|
||||
target: '_blank',
|
||||
rel: 'noopener',
|
||||
},
|
||||
})
|
||||
},
|
||||
}),
|
||||
|
||||
// https://github.com/antfu/vite-plugin-pwa
|
||||
VitePWA({
|
||||
registerType: 'autoUpdate',
|
||||
includeAssets: ['favicon.svg', 'robots.txt', 'safari-pinned-tab.svg'],
|
||||
manifest: {
|
||||
name: 'Vitesse',
|
||||
short_name: 'Vitesse',
|
||||
theme_color: '#ffffff',
|
||||
icons: [
|
||||
{
|
||||
src: '/pwa-192x192.png',
|
||||
sizes: '192x192',
|
||||
type: 'image/png',
|
||||
},
|
||||
{
|
||||
src: '/pwa-512x512.png',
|
||||
sizes: '512x512',
|
||||
type: 'image/png',
|
||||
},
|
||||
{
|
||||
src: '/pwa-512x512.png',
|
||||
sizes: '512x512',
|
||||
type: 'image/png',
|
||||
purpose: 'any maskable',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
|
||||
// https://github.com/intlify/bundle-tools/tree/main/packages/vite-plugin-vue-i18n
|
||||
VueI18n({
|
||||
runtimeOnly: true,
|
||||
compositionOnly: true,
|
||||
include: [path.resolve(__dirname, 'locales/**')],
|
||||
}),
|
||||
],
|
||||
|
||||
server: {
|
||||
fs: {
|
||||
strict: true,
|
||||
},
|
||||
},
|
||||
|
||||
// https://github.com/antfu/vite-ssg
|
||||
ssgOptions: {
|
||||
script: 'async',
|
||||
formatting: 'minify',
|
||||
},
|
||||
|
||||
optimizeDeps: {
|
||||
include: [
|
||||
'vue',
|
||||
'vue-router',
|
||||
'@vueuse/core',
|
||||
],
|
||||
exclude: [
|
||||
'vue-demi',
|
||||
],
|
||||
},
|
||||
})
|
||||
763
windi.config.ts
Normal file
763
windi.config.ts
Normal file
@@ -0,0 +1,763 @@
|
||||
import { defineConfig } from 'windicss/helpers'
|
||||
import colors from 'windicss/colors'
|
||||
import typography from 'windicss/plugin/typography'
|
||||
|
||||
export default defineConfig({
|
||||
darkMode: 'class',
|
||||
attributify: true,
|
||||
|
||||
plugins: [
|
||||
typography(),
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
typography: {
|
||||
DEFAULT: {
|
||||
css: {
|
||||
maxWidth: '65ch',
|
||||
color: 'inherit',
|
||||
a: {
|
||||
'color': 'inherit',
|
||||
'opacity': 0.75,
|
||||
'fontWeight': '500',
|
||||
'textDecoration': 'underline',
|
||||
'&:hover': {
|
||||
opacity: 1,
|
||||
color: colors.teal[600],
|
||||
},
|
||||
},
|
||||
b: { color: 'inherit' },
|
||||
strong: { color: 'inherit' },
|
||||
em: { color: 'inherit' },
|
||||
h1: { color: 'inherit' },
|
||||
h2: { color: 'inherit' },
|
||||
h3: { color: 'inherit' },
|
||||
h4: { color: 'inherit' },
|
||||
code: { color: 'inherit' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
screens: {
|
||||
'sm': '640px',
|
||||
'md': '768px',
|
||||
'lg': '1024px',
|
||||
'xl': '1280px',
|
||||
'2xl': '1536px',
|
||||
},
|
||||
colors: {
|
||||
transparent: 'transparent',
|
||||
current: 'currentColor',
|
||||
black: colors.black,
|
||||
white: colors.white,
|
||||
rose: colors.rose,
|
||||
pink: colors.pink,
|
||||
fuchsia: colors.fuchsia,
|
||||
purple: colors.purple,
|
||||
violet: colors.violet,
|
||||
indigo: colors.indigo,
|
||||
blue: colors.blue,
|
||||
lightBlue: colors.lightBlue,
|
||||
cyan: colors.cyan,
|
||||
teal: colors.teal,
|
||||
emerald: colors.emerald,
|
||||
green: colors.green,
|
||||
lime: colors.lime,
|
||||
yellow: colors.yellow,
|
||||
amber: colors.amber,
|
||||
orange: colors.orange,
|
||||
red: colors.red,
|
||||
warmGray: colors.warmGray,
|
||||
trueGray: colors.trueGray,
|
||||
gray: colors.gray,
|
||||
coolGray: colors.coolGray,
|
||||
blueGray: colors.blueGray,
|
||||
dark: colors.dark,
|
||||
light: colors.light,
|
||||
},
|
||||
spacing: {
|
||||
'px': '1px',
|
||||
'0': '0px',
|
||||
'0.5': '0.125rem',
|
||||
'1': '0.25rem',
|
||||
'1.5': '0.375rem',
|
||||
'2': '0.5rem',
|
||||
'2.5': '0.625rem',
|
||||
'3': '0.75rem',
|
||||
'3.5': '0.875rem',
|
||||
'4': '1rem',
|
||||
'5': '1.25rem',
|
||||
'6': '1.5rem',
|
||||
'7': '1.75rem',
|
||||
'8': '2rem',
|
||||
'9': '2.25rem',
|
||||
'10': '2.5rem',
|
||||
'11': '2.75rem',
|
||||
'12': '3rem',
|
||||
'14': '3.5rem',
|
||||
'16': '4rem',
|
||||
'20': '5rem',
|
||||
'24': '6rem',
|
||||
'28': '7rem',
|
||||
'32': '8rem',
|
||||
'36': '9rem',
|
||||
'40': '10rem',
|
||||
'44': '11rem',
|
||||
'48': '12rem',
|
||||
'52': '13rem',
|
||||
'56': '14rem',
|
||||
'60': '15rem',
|
||||
'64': '16rem',
|
||||
'72': '18rem',
|
||||
'80': '20rem',
|
||||
'96': '24rem',
|
||||
'1/2': '50%',
|
||||
'1/3': '33.333333%',
|
||||
'2/3': '66.666667%',
|
||||
'1/4': '25%',
|
||||
'2/4': '50%',
|
||||
'3/4': '75%',
|
||||
'1/5': '20%',
|
||||
'2/5': '40%',
|
||||
'3/5': '60%',
|
||||
'4/5': '80%',
|
||||
'1/6': '16.666667%',
|
||||
'2/6': '33.333333%',
|
||||
'3/6': '50%',
|
||||
'4/6': '66.666667%',
|
||||
'5/6': '83.333333%',
|
||||
'1/12': '8.333333%',
|
||||
'2/12': '16.666667%',
|
||||
'3/12': '25%',
|
||||
'4/12': '33.333333%',
|
||||
'5/12': '41.666667%',
|
||||
'6/12': '50%',
|
||||
'7/12': '58.333333%',
|
||||
'8/12': '66.666667%',
|
||||
'9/12': '75%',
|
||||
'10/12': '83.333333%',
|
||||
'11/12': '91.666667%',
|
||||
'full': '100%',
|
||||
},
|
||||
animation: {
|
||||
none: 'none',
|
||||
spin: 'spin 1s linear infinite',
|
||||
ping: 'ping 1s cubic-bezier(0, 0, 0.2, 1) infinite',
|
||||
pulse: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',
|
||||
bounce: 'bounce 1s infinite',
|
||||
},
|
||||
backgroundColor: theme => theme('colors'),
|
||||
backgroundImage: {
|
||||
'none': 'none',
|
||||
'gradient-to-t': 'linear-gradient(to top, var(--tw-gradient-stops))',
|
||||
'gradient-to-tr': 'linear-gradient(to top right, var(--tw-gradient-stops))',
|
||||
'gradient-to-r': 'linear-gradient(to right, var(--tw-gradient-stops))',
|
||||
'gradient-to-br': 'linear-gradient(to bottom right, var(--tw-gradient-stops))',
|
||||
'gradient-to-b': 'linear-gradient(to bottom, var(--tw-gradient-stops))',
|
||||
'gradient-to-bl': 'linear-gradient(to bottom left, var(--tw-gradient-stops))',
|
||||
'gradient-to-l': 'linear-gradient(to left, var(--tw-gradient-stops))',
|
||||
'gradient-to-tl': 'linear-gradient(to top left, var(--tw-gradient-stops))',
|
||||
},
|
||||
backgroundOpacity: theme => theme('opacity'),
|
||||
backgroundPosition: {
|
||||
'bottom': 'bottom',
|
||||
'center': 'center',
|
||||
'left': 'left',
|
||||
'left-bottom': 'left bottom',
|
||||
'left-top': 'left top',
|
||||
'right': 'right',
|
||||
'right-bottom': 'right bottom',
|
||||
'right-top': 'right top',
|
||||
'top': 'top',
|
||||
},
|
||||
backgroundSize: {
|
||||
auto: 'auto',
|
||||
cover: 'cover',
|
||||
contain: 'contain',
|
||||
},
|
||||
borderColor: theme => ({
|
||||
...theme('colors'),
|
||||
DEFAULT: theme('colors.gray.200', 'currentColor'),
|
||||
}),
|
||||
borderOpacity: theme => theme('opacity'),
|
||||
borderRadius: {
|
||||
'none': '0px',
|
||||
'sm': '0.125rem',
|
||||
'DEFAULT': '0.25rem',
|
||||
'md': '0.375rem',
|
||||
'lg': '0.5rem',
|
||||
'xl': '0.75rem',
|
||||
'2xl': '1rem',
|
||||
'3xl': '1.5rem',
|
||||
'full': '9999px',
|
||||
},
|
||||
borderWidth: {
|
||||
DEFAULT: '1px',
|
||||
0: '0px',
|
||||
2: '2px',
|
||||
4: '4px',
|
||||
6: '6px',
|
||||
8: '8px',
|
||||
},
|
||||
boxShadow: {
|
||||
'sm': '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
|
||||
'DEFAULT': '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
|
||||
'md': '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
|
||||
'lg': '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
|
||||
'xl': '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
|
||||
'2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
|
||||
'inner': 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',
|
||||
'white': '2px 4px 8px rgb(0 0 0 / 8%)',
|
||||
'black': '2px 4px 12px rgb(255 255 255 / 8%)',
|
||||
'none': 'none',
|
||||
},
|
||||
container: {},
|
||||
cursor: {
|
||||
'auto': 'auto',
|
||||
'default': 'default',
|
||||
'pointer': 'pointer',
|
||||
'wait': 'wait',
|
||||
'text': 'text',
|
||||
'move': 'move',
|
||||
'not-allowed': 'not-allowed',
|
||||
},
|
||||
divideColor: theme => theme('borderColor'),
|
||||
divideOpacity: theme => theme('borderOpacity'),
|
||||
divideWidth: theme => theme('borderWidth'),
|
||||
fill: theme => ({
|
||||
'current': 'currentColor',
|
||||
'adonis-dark': theme('colors.purple.500'),
|
||||
'adonis-light': theme('colors.purple.800'),
|
||||
'twitter-dark': theme('colors.cyan.400'),
|
||||
'twitter-light': theme('colors.cyan.500'),
|
||||
'heart': theme('colors.red.500'),
|
||||
}),
|
||||
flex: {
|
||||
1: '1 1 0%',
|
||||
auto: '1 1 auto',
|
||||
initial: '0 1 auto',
|
||||
none: 'none',
|
||||
},
|
||||
flexGrow: {
|
||||
0: '0',
|
||||
DEFAULT: '1',
|
||||
},
|
||||
flexShrink: {
|
||||
0: '0',
|
||||
DEFAULT: '1',
|
||||
},
|
||||
fontFamily: {
|
||||
sans: [
|
||||
'Raleway',
|
||||
'ui-sans-serif',
|
||||
'system-ui',
|
||||
'-apple-system',
|
||||
'BlinkMacSystemFont',
|
||||
'"Segoe UI"',
|
||||
'Roboto',
|
||||
'"Helvetica Neue"',
|
||||
'Arial',
|
||||
'"Noto Sans"',
|
||||
'sans-serif',
|
||||
'"Apple Color Emoji"',
|
||||
'"Segoe UI Emoji"',
|
||||
'"Segoe UI Symbol"',
|
||||
'"Noto Color Emoji"',
|
||||
],
|
||||
serif: ['Raleway', 'ui-serif', 'Georgia', 'Cambria', '"Times New Roman"', 'Times', 'serif'],
|
||||
mono: [
|
||||
'Raleway',
|
||||
'ui-monospace',
|
||||
'SFMono-Regular',
|
||||
'Menlo',
|
||||
'Monaco',
|
||||
'Consolas',
|
||||
'"Liberation Mono"',
|
||||
'"Courier New"',
|
||||
'monospace',
|
||||
],
|
||||
color: ['Roboto', 'ui-sans-serif', 'system-ui', '-apple-system', 'sans-serif'],
|
||||
},
|
||||
fontSize: {
|
||||
'xs': ['0.75rem', { lineHeight: '1rem' }],
|
||||
'sm': ['0.875rem', { lineHeight: '1.25rem' }],
|
||||
'base': ['1rem', { lineHeight: '1.5rem' }],
|
||||
'lg': ['1.125rem', { lineHeight: '1.75rem' }],
|
||||
'xl': ['1.25rem', { lineHeight: '1.75rem' }],
|
||||
'2xl': ['1.5rem', { lineHeight: '2rem' }],
|
||||
'3xl': ['1.875rem', { lineHeight: '2.25rem' }],
|
||||
'4xl': ['2.25rem', { lineHeight: '2.5rem' }],
|
||||
'5xl': ['3rem', { lineHeight: '1' }],
|
||||
'6xl': ['3.75rem', { lineHeight: '1' }],
|
||||
'7xl': ['4.5rem', { lineHeight: '1' }],
|
||||
'8xl': ['6rem', { lineHeight: '1' }],
|
||||
'9xl': ['8rem', { lineHeight: '1' }],
|
||||
},
|
||||
fontWeight: {
|
||||
thin: '100',
|
||||
extralight: '200',
|
||||
light: '300',
|
||||
normal: '400',
|
||||
medium: '500',
|
||||
semibold: '600',
|
||||
bold: '700',
|
||||
extrabold: '800',
|
||||
black: '900',
|
||||
},
|
||||
gap: theme => theme('spacing'),
|
||||
gradientColorStops: theme => theme('colors'),
|
||||
gridAutoColumns: {
|
||||
auto: 'auto',
|
||||
min: 'min-content',
|
||||
max: 'max-content',
|
||||
fr: 'minmax(0, 1fr)',
|
||||
},
|
||||
gridAutoRows: {
|
||||
auto: 'auto',
|
||||
min: 'min-content',
|
||||
max: 'max-content',
|
||||
fr: 'minmax(0, 1fr)',
|
||||
},
|
||||
gridColumn: {
|
||||
'auto': 'auto',
|
||||
'span-1': 'span 1 / span 1',
|
||||
'span-2': 'span 2 / span 2',
|
||||
'span-3': 'span 3 / span 3',
|
||||
'span-4': 'span 4 / span 4',
|
||||
'span-5': 'span 5 / span 5',
|
||||
'span-6': 'span 6 / span 6',
|
||||
'span-7': 'span 7 / span 7',
|
||||
'span-8': 'span 8 / span 8',
|
||||
'span-9': 'span 9 / span 9',
|
||||
'span-10': 'span 10 / span 10',
|
||||
'span-11': 'span 11 / span 11',
|
||||
'span-12': 'span 12 / span 12',
|
||||
'span-full': '1 / -1',
|
||||
},
|
||||
gridColumnEnd: {
|
||||
auto: 'auto',
|
||||
1: '1',
|
||||
2: '2',
|
||||
3: '3',
|
||||
4: '4',
|
||||
5: '5',
|
||||
6: '6',
|
||||
7: '7',
|
||||
8: '8',
|
||||
9: '9',
|
||||
10: '10',
|
||||
11: '11',
|
||||
12: '12',
|
||||
13: '13',
|
||||
},
|
||||
gridColumnStart: {
|
||||
auto: 'auto',
|
||||
1: '1',
|
||||
2: '2',
|
||||
3: '3',
|
||||
4: '4',
|
||||
5: '5',
|
||||
6: '6',
|
||||
7: '7',
|
||||
8: '8',
|
||||
9: '9',
|
||||
10: '10',
|
||||
11: '11',
|
||||
12: '12',
|
||||
13: '13',
|
||||
},
|
||||
gridRow: {
|
||||
'auto': 'auto',
|
||||
'span-1': 'span 1 / span 1',
|
||||
'span-2': 'span 2 / span 2',
|
||||
'span-3': 'span 3 / span 3',
|
||||
'span-4': 'span 4 / span 4',
|
||||
'span-5': 'span 5 / span 5',
|
||||
'span-6': 'span 6 / span 6',
|
||||
'span-full': '1 / -1',
|
||||
},
|
||||
gridRowStart: {
|
||||
auto: 'auto',
|
||||
1: '1',
|
||||
2: '2',
|
||||
3: '3',
|
||||
4: '4',
|
||||
5: '5',
|
||||
6: '6',
|
||||
7: '7',
|
||||
},
|
||||
gridRowEnd: {
|
||||
auto: 'auto',
|
||||
1: '1',
|
||||
2: '2',
|
||||
3: '3',
|
||||
4: '4',
|
||||
5: '5',
|
||||
6: '6',
|
||||
7: '7',
|
||||
},
|
||||
transformOrigin: {
|
||||
'center': 'center',
|
||||
'top': 'top',
|
||||
'top-right': 'top right',
|
||||
'right': 'right',
|
||||
'bottom-right': 'bottom right',
|
||||
'bottom': 'bottom',
|
||||
'bottom-left': 'bottom left',
|
||||
'left': 'left',
|
||||
'top-left': 'top left',
|
||||
},
|
||||
gridTemplateColumns: {
|
||||
none: 'none',
|
||||
1: 'repeat(1, minmax(0, 1fr))',
|
||||
2: 'repeat(2, minmax(0, 1fr))',
|
||||
3: 'repeat(3, minmax(0, 1fr))',
|
||||
4: 'repeat(4, minmax(0, 1fr))',
|
||||
5: 'repeat(5, minmax(0, 1fr))',
|
||||
6: 'repeat(6, minmax(0, 1fr))',
|
||||
7: 'repeat(7, minmax(0, 1fr))',
|
||||
8: 'repeat(8, minmax(0, 1fr))',
|
||||
9: 'repeat(9, minmax(0, 1fr))',
|
||||
10: 'repeat(10, minmax(0, 1fr))',
|
||||
11: 'repeat(11, minmax(0, 1fr))',
|
||||
12: 'repeat(12, minmax(0, 1fr))',
|
||||
},
|
||||
gridTemplateRows: {
|
||||
none: 'none',
|
||||
1: 'repeat(1, minmax(0, 1fr))',
|
||||
2: 'repeat(2, minmax(0, 1fr))',
|
||||
3: 'repeat(3, minmax(0, 1fr))',
|
||||
4: 'repeat(4, minmax(0, 1fr))',
|
||||
5: 'repeat(5, minmax(0, 1fr))',
|
||||
6: 'repeat(6, minmax(0, 1fr))',
|
||||
},
|
||||
height: theme => ({
|
||||
auto: 'auto',
|
||||
...theme('spacing'),
|
||||
screen: '100vh',
|
||||
}),
|
||||
inset: (theme, { negative }) => ({
|
||||
'auto': 'auto',
|
||||
...theme('spacing'),
|
||||
...negative(theme('spacing')),
|
||||
'1/2': '50%',
|
||||
'1/3': '33.333333%',
|
||||
'2/3': '66.666667%',
|
||||
'1/4': '25%',
|
||||
'2/4': '50%',
|
||||
'3/4': '75%',
|
||||
'full': '100%',
|
||||
'-1/2': '-50%',
|
||||
'-1/3': '-33.333333%',
|
||||
'-2/3': '-66.666667%',
|
||||
'-1/4': '-25%',
|
||||
'-2/4': '-50%',
|
||||
'-3/4': '-75%',
|
||||
'-full': '-100%',
|
||||
}),
|
||||
keyframes: {
|
||||
spin: {
|
||||
to: {
|
||||
transform: 'rotate(360deg)',
|
||||
},
|
||||
},
|
||||
ping: {
|
||||
'75%, 100%': {
|
||||
transform: 'scale(2)',
|
||||
opacity: '0',
|
||||
},
|
||||
},
|
||||
pulse: {
|
||||
'50%': {
|
||||
opacity: '.5',
|
||||
},
|
||||
},
|
||||
bounce: {
|
||||
'0%, 100%': {
|
||||
transform: 'translateY(-25%)',
|
||||
animationTimingFunction: 'cubic-bezier(0.8,0,1,1)',
|
||||
},
|
||||
'50%': {
|
||||
transform: 'none',
|
||||
animationTimingFunction: 'cubic-bezier(0,0,0.2,1)',
|
||||
},
|
||||
},
|
||||
},
|
||||
letterSpacing: {
|
||||
tighter: '-0.05em',
|
||||
tight: '-0.025em',
|
||||
normal: '0em',
|
||||
wide: '0.025em',
|
||||
wider: '0.05em',
|
||||
widest: '0.1em',
|
||||
},
|
||||
lineHeight: {
|
||||
none: '1',
|
||||
tight: '1.25',
|
||||
snug: '1.375',
|
||||
normal: '1.5',
|
||||
relaxed: '1.625',
|
||||
loose: '2',
|
||||
3: '.75rem',
|
||||
4: '1rem',
|
||||
5: '1.25rem',
|
||||
6: '1.5rem',
|
||||
7: '1.75rem',
|
||||
8: '2rem',
|
||||
9: '2.25rem',
|
||||
10: '2.5rem',
|
||||
},
|
||||
listStyleType: {
|
||||
none: 'none',
|
||||
disc: 'disc',
|
||||
decimal: 'decimal',
|
||||
},
|
||||
margin: (theme, { negative }) => ({
|
||||
auto: 'auto',
|
||||
...theme('spacing'),
|
||||
...negative(theme('spacing')),
|
||||
}),
|
||||
maxHeight: theme => ({
|
||||
...theme('spacing'),
|
||||
full: '100%',
|
||||
screen: '100vh',
|
||||
}),
|
||||
maxWidth: (theme, { breakpoints }) => ({
|
||||
'none': 'none',
|
||||
'0': '0rem',
|
||||
'xs': '20rem',
|
||||
'sm': '24rem',
|
||||
'md': '28rem',
|
||||
'lg': '32rem',
|
||||
'xl': '36rem',
|
||||
'2xl': '42rem',
|
||||
'3xl': '48rem',
|
||||
'4xl': '56rem',
|
||||
'5xl': '64rem',
|
||||
'6xl': '72rem',
|
||||
'7xl': '80rem',
|
||||
'full': '100%',
|
||||
'min': 'min-content',
|
||||
'max': 'max-content',
|
||||
'prose': '65ch',
|
||||
...breakpoints(theme('screens')),
|
||||
}),
|
||||
minHeight: {
|
||||
0: '0px',
|
||||
full: '100%',
|
||||
screen: '100vh',
|
||||
},
|
||||
minWidth: {
|
||||
0: '0px',
|
||||
full: '100%',
|
||||
min: 'min-content',
|
||||
max: 'max-content',
|
||||
},
|
||||
objectPosition: {
|
||||
'bottom': 'bottom',
|
||||
'center': 'center',
|
||||
'left': 'left',
|
||||
'left-bottom': 'left bottom',
|
||||
'left-top': 'left top',
|
||||
'right': 'right',
|
||||
'right-bottom': 'right bottom',
|
||||
'right-top': 'right top',
|
||||
'top': 'top',
|
||||
},
|
||||
opacity: {
|
||||
0: '0',
|
||||
5: '0.05',
|
||||
10: '0.1',
|
||||
20: '0.2',
|
||||
25: '0.25',
|
||||
30: '0.3',
|
||||
40: '0.4',
|
||||
50: '0.5',
|
||||
60: '0.6',
|
||||
70: '0.7',
|
||||
75: '0.75',
|
||||
80: '0.8',
|
||||
90: '0.9',
|
||||
95: '0.95',
|
||||
100: '1',
|
||||
},
|
||||
order: {
|
||||
first: '-9999',
|
||||
last: '9999',
|
||||
none: '0',
|
||||
1: '1',
|
||||
2: '2',
|
||||
3: '3',
|
||||
4: '4',
|
||||
5: '5',
|
||||
6: '6',
|
||||
7: '7',
|
||||
8: '8',
|
||||
9: '9',
|
||||
10: '10',
|
||||
11: '11',
|
||||
12: '12',
|
||||
},
|
||||
outline: {
|
||||
none: ['2px solid transparent', '2px'],
|
||||
white: ['2px dotted white', '2px'],
|
||||
black: ['2px dotted black', '2px'],
|
||||
},
|
||||
padding: theme => theme('spacing'),
|
||||
placeholderColor: theme => theme('colors'),
|
||||
placeholderOpacity: theme => theme('opacity'),
|
||||
ringColor: theme => ({
|
||||
DEFAULT: theme('colors.blue.500', '#3b82f6'),
|
||||
...theme('colors'),
|
||||
}),
|
||||
ringOffsetColor: theme => theme('colors'),
|
||||
ringOffsetWidth: {
|
||||
0: '0px',
|
||||
1: '1px',
|
||||
2: '2px',
|
||||
4: '4px',
|
||||
8: '8px',
|
||||
},
|
||||
ringOpacity: theme => ({
|
||||
DEFAULT: '0.5',
|
||||
...theme('opacity'),
|
||||
}),
|
||||
ringWidth: {
|
||||
DEFAULT: '3px',
|
||||
0: '0px',
|
||||
1: '1px',
|
||||
2: '2px',
|
||||
4: '4px',
|
||||
8: '8px',
|
||||
},
|
||||
rotate: {
|
||||
'-180': '-180deg',
|
||||
'-90': '-90deg',
|
||||
'-45': '-45deg',
|
||||
'-12': '-12deg',
|
||||
'-6': '-6deg',
|
||||
'-3': '-3deg',
|
||||
'-2': '-2deg',
|
||||
'-1': '-1deg',
|
||||
'0': '0deg',
|
||||
'1': '1deg',
|
||||
'2': '2deg',
|
||||
'3': '3deg',
|
||||
'6': '6deg',
|
||||
'12': '12deg',
|
||||
'45': '45deg',
|
||||
'90': '90deg',
|
||||
'180': '180deg',
|
||||
},
|
||||
scale: {
|
||||
0: '0',
|
||||
50: '.5',
|
||||
75: '.75',
|
||||
90: '.9',
|
||||
95: '.95',
|
||||
100: '1',
|
||||
105: '1.05',
|
||||
110: '1.1',
|
||||
125: '1.25',
|
||||
150: '1.5',
|
||||
},
|
||||
skew: {
|
||||
'-12': '-12deg',
|
||||
'-6': '-6deg',
|
||||
'-3': '-3deg',
|
||||
'-2': '-2deg',
|
||||
'-1': '-1deg',
|
||||
'0': '0deg',
|
||||
'1': '1deg',
|
||||
'2': '2deg',
|
||||
'3': '3deg',
|
||||
'6': '6deg',
|
||||
'12': '12deg',
|
||||
},
|
||||
space: (theme, { negative }) => ({
|
||||
...theme('spacing'),
|
||||
...negative(theme('spacing')),
|
||||
}),
|
||||
stroke: {
|
||||
current: 'currentColor',
|
||||
},
|
||||
strokeWidth: {
|
||||
0: '0',
|
||||
1: '1',
|
||||
2: '2',
|
||||
},
|
||||
textColor: theme => theme('colors'),
|
||||
textOpacity: theme => theme('opacity'),
|
||||
transitionDuration: {
|
||||
DEFAULT: '150ms',
|
||||
75: '75ms',
|
||||
100: '100ms',
|
||||
150: '150ms',
|
||||
200: '200ms',
|
||||
300: '300ms',
|
||||
500: '500ms',
|
||||
700: '700ms',
|
||||
1000: '1000ms',
|
||||
},
|
||||
transitionDelay: {
|
||||
75: '75ms',
|
||||
100: '100ms',
|
||||
150: '150ms',
|
||||
200: '200ms',
|
||||
300: '300ms',
|
||||
500: '500ms',
|
||||
700: '700ms',
|
||||
1000: '1000ms',
|
||||
},
|
||||
transitionProperty: {
|
||||
none: 'none',
|
||||
all: 'all',
|
||||
DEFAULT: 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform',
|
||||
colors: 'background-color, border-color, color, fill, stroke',
|
||||
opacity: 'opacity',
|
||||
shadow: 'box-shadow',
|
||||
transform: 'transform',
|
||||
},
|
||||
transitionTimingFunction: {
|
||||
'DEFAULT': 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||
'linear': 'linear',
|
||||
'in': 'cubic-bezier(0.4, 0, 1, 1)',
|
||||
'out': 'cubic-bezier(0, 0, 0.2, 1)',
|
||||
'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||
},
|
||||
translate: (theme, { negative }) => ({
|
||||
...theme('spacing'),
|
||||
...negative(theme('spacing')),
|
||||
'1/2': '50%',
|
||||
'1/3': '33.333333%',
|
||||
'2/3': '66.666667%',
|
||||
'1/4': '25%',
|
||||
'2/4': '50%',
|
||||
'3/4': '75%',
|
||||
'full': '100%',
|
||||
'-1/2': '-50%',
|
||||
'-1/3': '-33.333333%',
|
||||
'-2/3': '-66.666667%',
|
||||
'-1/4': '-25%',
|
||||
'-2/4': '-50%',
|
||||
'-3/4': '-75%',
|
||||
'-full': '-100%',
|
||||
}),
|
||||
width: theme => ({
|
||||
auto: 'auto',
|
||||
...theme('spacing'),
|
||||
screen: '100vw',
|
||||
min: 'min-content',
|
||||
max: 'max-content',
|
||||
}),
|
||||
zIndex: {
|
||||
auto: 'auto',
|
||||
0: '0',
|
||||
10: '10',
|
||||
20: '20',
|
||||
30: '30',
|
||||
40: '40',
|
||||
50: '50',
|
||||
},
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user