mirror of
https://github.com/ArthurDanjou/artdanj-resume.git
synced 2026-01-14 15:54:06 +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
|
||||
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
.DS_Store
|
||||
.vite-ssg-dist
|
||||
.vite-ssg-temp
|
||||
*.local
|
||||
dist
|
||||
dist-ssr
|
||||
node_modules
|
||||
.idea/
|
||||
*.log
|
||||
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.
|
||||
82
README.md
Normal file
82
README.md
Normal file
@@ -0,0 +1,82 @@
|
||||
<p align='center'>
|
||||
<img src='https://user-images.githubusercontent.com/11247099/111864893-a457fd00-899e-11eb-9f05-f4b88987541d.png' alt='Vitesse - Opinionated Vite Starter Template' width='600'/>
|
||||
</p>
|
||||
|
||||
<h6 align='center'>
|
||||
<a href="https://vitesse-lite.netlify.app/">Live Demo</a>
|
||||
</h6>
|
||||
|
||||
<h5 align='center'>
|
||||
<b>Lightweight version of <a href="https://github.com/antfu/vitesse">Vitesse</a></b>
|
||||
</h5>
|
||||
|
||||
<br>
|
||||
|
||||
## Features
|
||||
|
||||
- ⚡️ [Vue 3](https://github.com/vuejs/vue-next), [Vite 2](https://github.com/vitejs/vite), [pnpm](https://pnpm.js.org/), [ESBuild](https://github.com/evanw/esbuild) - born with fastness
|
||||
|
||||
- 🗂 [File based routing](./src/pages)
|
||||
|
||||
- 📦 [Components auto importing](./src/components)
|
||||
|
||||
- 🎨 [UnoCSS](https://github.com/antfu/unocss) - The instant on-demand atomic CSS engine.
|
||||
|
||||
- 😃 Use icons from any icon sets in [Pure CSS](https://github.com/antfu/unocss/tree/main/packages/preset-icons)
|
||||
|
||||
- 🔥 Use the [new `<script setup>` style](https://github.com/vuejs/rfcs/pull/227)
|
||||
|
||||
- ✅ Use [Vitest](http://vitest.dev/) for unit and components testing
|
||||
|
||||
- 🦾 TypeScript, of course
|
||||
|
||||
- ☁️ Deploy on Netlify, zero-config
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
See [Vitesse](https://github.com/antfu/vitesse) for full featureset.
|
||||
|
||||
|
||||
## Dropped Features from [Vitesse](https://github.com/antfu/vitesse)
|
||||
|
||||
- ~~i18n~~
|
||||
- ~~Layouts~~
|
||||
- ~~SSG~~
|
||||
- ~~PWA~~
|
||||
- ~~Markdown~~
|
||||
|
||||
## Pre-packed
|
||||
|
||||
### UI Frameworks
|
||||
|
||||
- [UnoCSS](https://github.com/antfu/unocss) - The instant on-demand atomic CSS engine.
|
||||
|
||||
### Icons
|
||||
|
||||
- [Iconify](https://iconify.design) - use icons from any icon sets [🔍Icônes](https://icones.netlify.app/)
|
||||
- [Pure CSS Icons via UnoCSS](https://github.com/antfu/unocss/tree/main/packages/preset-icons)
|
||||
|
||||
### Plugins
|
||||
|
||||
- [Vue Router](https://github.com/vuejs/vue-router)
|
||||
- [`vite-plugin-pages`](https://github.com/hannoeru/vite-plugin-pages) - file system based routing
|
||||
- [`unplugin-auto-import`](https://github.com/antfu/unplugin-auto-import) - Directly use Vue Composition API and others without importing
|
||||
- [`unplugin-vue-components`](https://github.com/antfu/unplugin-vue-components) - components auto import
|
||||
- [VueUse](https://github.com/antfu/vueuse) - collection of useful composition APIs
|
||||
|
||||
## Try it now!
|
||||
|
||||
### GitHub Template
|
||||
|
||||
[Create a repo from this template on GitHub](https://github.com/antfu/vitesse-lite/generate).
|
||||
|
||||
### Clone to local
|
||||
|
||||
If you prefer to do it manually with the cleaner git history
|
||||
|
||||
```bash
|
||||
npx degit antfu/vitesse-lite my-vitesse-app
|
||||
cd my-vitesse-app
|
||||
pnpm i # If you don't have pnpm installed, run: npm install -g pnpm
|
||||
```
|
||||
228
auto-imports.d.ts
vendored
Normal file
228
auto-imports.d.ts
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
// Generated by 'unplugin-auto-import'
|
||||
// We suggest you to commit this file into source control
|
||||
declare global {
|
||||
const afterAll: typeof import('vitest')['afterAll']
|
||||
const afterEach: typeof import('vitest')['afterEach']
|
||||
const assert: typeof import('vitest')['assert']
|
||||
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
|
||||
const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
|
||||
const beforeAll: typeof import('vitest')['beforeAll']
|
||||
const beforeEach: typeof import('vitest')['beforeEach']
|
||||
const biSyncRef: typeof import('@vueuse/core')['biSyncRef']
|
||||
const chai: typeof import('vitest')['chai']
|
||||
const computed: typeof import('vue')['computed']
|
||||
const computedInject: typeof import('@vueuse/core')['computedInject']
|
||||
const controlledComputed: typeof import('@vueuse/core')['controlledComputed']
|
||||
const controlledRef: typeof import('@vueuse/core')['controlledRef']
|
||||
const createApp: typeof import('vue')['createApp']
|
||||
const createEventHook: typeof import('@vueuse/core')['createEventHook']
|
||||
const createGlobalState: typeof import('@vueuse/core')['createGlobalState']
|
||||
const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn']
|
||||
const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable']
|
||||
const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn']
|
||||
const customRef: typeof import('vue')['customRef']
|
||||
const debouncedRef: typeof import('@vueuse/core')['debouncedRef']
|
||||
const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch']
|
||||
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
|
||||
const defineComponent: typeof import('vue')['defineComponent']
|
||||
const describe: typeof import('vitest')['describe']
|
||||
const eagerComputed: typeof import('@vueuse/core')['eagerComputed']
|
||||
const effectScope: typeof import('vue')['effectScope']
|
||||
const EffectScope: typeof import('vue')['EffectScope']
|
||||
const expect: typeof import('vitest')['expect']
|
||||
const extendRef: typeof import('@vueuse/core')['extendRef']
|
||||
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||
const h: typeof import('vue')['h']
|
||||
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
|
||||
const inject: typeof import('vue')['inject']
|
||||
const isDefined: typeof import('@vueuse/core')['isDefined']
|
||||
const isReadonly: typeof import('vue')['isReadonly']
|
||||
const isRef: typeof import('vue')['isRef']
|
||||
const it: typeof import('vitest')['it']
|
||||
const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable']
|
||||
const markRaw: typeof import('vue')['markRaw']
|
||||
const nextTick: typeof import('vue')['nextTick']
|
||||
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 onClickOutside: typeof import('@vueuse/core')['onClickOutside']
|
||||
const onDeactivated: typeof import('vue')['onDeactivated']
|
||||
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
|
||||
const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke']
|
||||
const onLongPress: typeof import('@vueuse/core')['onLongPress']
|
||||
const onMounted: typeof import('vue')['onMounted']
|
||||
const onRenderTracked: typeof import('vue')['onRenderTracked']
|
||||
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
|
||||
const onScopeDispose: typeof import('vue')['onScopeDispose']
|
||||
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
|
||||
const onStartTyping: typeof import('@vueuse/core')['onStartTyping']
|
||||
const onUnmounted: typeof import('vue')['onUnmounted']
|
||||
const onUpdated: typeof import('vue')['onUpdated']
|
||||
const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
|
||||
const provide: typeof import('vue')['provide']
|
||||
const reactify: typeof import('@vueuse/core')['reactify']
|
||||
const reactifyObject: typeof import('@vueuse/core')['reactifyObject']
|
||||
const reactive: typeof import('vue')['reactive']
|
||||
const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed']
|
||||
const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit']
|
||||
const reactivePick: typeof import('@vueuse/core')['reactivePick']
|
||||
const readonly: typeof import('vue')['readonly']
|
||||
const ref: typeof import('vue')['ref']
|
||||
const refDefault: typeof import('@vueuse/core')['refDefault']
|
||||
const resolveComponent: typeof import('vue')['resolveComponent']
|
||||
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||
const shallowRef: typeof import('vue')['shallowRef']
|
||||
const suite: typeof import('vitest')['suite']
|
||||
const syncRef: typeof import('@vueuse/core')['syncRef']
|
||||
const templateRef: typeof import('@vueuse/core')['templateRef']
|
||||
const test: typeof import('vitest')['test']
|
||||
const throttledRef: typeof import('@vueuse/core')['throttledRef']
|
||||
const throttledWatch: typeof import('@vueuse/core')['throttledWatch']
|
||||
const toRaw: typeof import('vue')['toRaw']
|
||||
const toReactive: typeof import('@vueuse/core')['toReactive']
|
||||
const toRef: typeof import('vue')['toRef']
|
||||
const toRefs: typeof import('vue')['toRefs']
|
||||
const triggerRef: typeof import('vue')['triggerRef']
|
||||
const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount']
|
||||
const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted']
|
||||
const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose']
|
||||
const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted']
|
||||
const unref: typeof import('vue')['unref']
|
||||
const unrefElement: typeof import('@vueuse/core')['unrefElement']
|
||||
const until: typeof import('@vueuse/core')['until']
|
||||
const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
|
||||
const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue']
|
||||
const useAsyncState: typeof import('@vueuse/core')['useAsyncState']
|
||||
const useAttrs: typeof import('vue')['useAttrs']
|
||||
const useBase64: typeof import('@vueuse/core')['useBase64']
|
||||
const useBattery: typeof import('@vueuse/core')['useBattery']
|
||||
const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints']
|
||||
const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel']
|
||||
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
|
||||
const useCached: typeof import('@vueuse/core')['useCached']
|
||||
const useClamp: typeof import('@vueuse/core')['useClamp']
|
||||
const useClipboard: typeof import('@vueuse/core')['useClipboard']
|
||||
const useColorMode: typeof import('@vueuse/core')['useColorMode']
|
||||
const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog']
|
||||
const useCounter: typeof import('@vueuse/core')['useCounter']
|
||||
const useCssModule: typeof import('vue')['useCssModule']
|
||||
const useCssVar: typeof import('@vueuse/core')['useCssVar']
|
||||
const useCssVars: typeof import('vue')['useCssVars']
|
||||
const useCycleList: typeof import('@vueuse/core')['useCycleList']
|
||||
const useDark: typeof import('@vueuse/core')['useDark']
|
||||
const useDebounce: typeof import('@vueuse/core')['useDebounce']
|
||||
const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory']
|
||||
const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn']
|
||||
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 useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia']
|
||||
const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility']
|
||||
const useDraggable: typeof import('@vueuse/core')['useDraggable']
|
||||
const useElementBounding: typeof import('@vueuse/core')['useElementBounding']
|
||||
const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint']
|
||||
const useElementHover: typeof import('@vueuse/core')['useElementHover']
|
||||
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 useEyeDropper: typeof import('@vueuse/core')['useEyeDropper']
|
||||
const useFavicon: typeof import('@vueuse/core')['useFavicon']
|
||||
const useFetch: typeof import('@vueuse/core')['useFetch']
|
||||
const useFocus: typeof import('@vueuse/core')['useFocus']
|
||||
const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin']
|
||||
const useFps: typeof import('@vueuse/core')['useFps']
|
||||
const useFullscreen: typeof import('@vueuse/core')['useFullscreen']
|
||||
const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
|
||||
const useHead: typeof import('@vueuse/head')['useHead']
|
||||
const useIdle: typeof import('@vueuse/core')['useIdle']
|
||||
const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll']
|
||||
const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver']
|
||||
const useInterval: typeof import('@vueuse/core')['useInterval']
|
||||
const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn']
|
||||
const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier']
|
||||
const useLastChanged: typeof import('@vueuse/core')['useLastChanged']
|
||||
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 useMemoize: typeof import('@vueuse/core')['useMemoize']
|
||||
const useMemory: typeof import('@vueuse/core')['useMemory']
|
||||
const useMounted: typeof import('@vueuse/core')['useMounted']
|
||||
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 useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage']
|
||||
const useNetwork: typeof import('@vueuse/core')['useNetwork']
|
||||
const useNow: typeof import('@vueuse/core')['useNow']
|
||||
const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination']
|
||||
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 usePointer: typeof import('@vueuse/core')['usePointer']
|
||||
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 useRoute: typeof import('vue-router')['useRoute']
|
||||
const useRouter: typeof import('vue-router')['useRouter']
|
||||
const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea']
|
||||
const useScriptTag: typeof import('@vueuse/core')['useScriptTag']
|
||||
const useScroll: typeof import('@vueuse/core')['useScroll']
|
||||
const useScrollLock: typeof import('@vueuse/core')['useScrollLock']
|
||||
const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage']
|
||||
const useShare: typeof import('@vueuse/core')['useShare']
|
||||
const useSlots: typeof import('vue')['useSlots']
|
||||
const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition']
|
||||
const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis']
|
||||
const useStorage: typeof import('@vueuse/core')['useStorage']
|
||||
const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync']
|
||||
const useStyleTag: typeof import('@vueuse/core')['useStyleTag']
|
||||
const useSwipe: typeof import('@vueuse/core')['useSwipe']
|
||||
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
|
||||
const useTextSelection: typeof import('@vueuse/core')['useTextSelection']
|
||||
const useThrottle: typeof import('@vueuse/core')['useThrottle']
|
||||
const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory']
|
||||
const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn']
|
||||
const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo']
|
||||
const useTimeout: typeof import('@vueuse/core')['useTimeout']
|
||||
const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn']
|
||||
const useTimestamp: typeof import('@vueuse/core')['useTimestamp']
|
||||
const useTitle: typeof import('@vueuse/core')['useTitle']
|
||||
const useToggle: typeof import('@vueuse/core')['useToggle']
|
||||
const useTransition: typeof import('@vueuse/core')['useTransition']
|
||||
const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
|
||||
const useUserMedia: typeof import('@vueuse/core')['useUserMedia']
|
||||
const useVibrate: typeof import('@vueuse/core')['useVibrate']
|
||||
const useVirtualList: typeof import('@vueuse/core')['useVirtualList']
|
||||
const useVModel: typeof import('@vueuse/core')['useVModel']
|
||||
const useVModels: typeof import('@vueuse/core')['useVModels']
|
||||
const useWakeLock: typeof import('@vueuse/core')['useWakeLock']
|
||||
const useWebNotification: typeof import('@vueuse/core')['useWebNotification']
|
||||
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']
|
||||
const vi: typeof import('vitest')['vi']
|
||||
const vitest: typeof import('vitest')['vitest']
|
||||
const watch: typeof import('vue')['watch']
|
||||
const watchAtMost: typeof import('@vueuse/core')['watchAtMost']
|
||||
const watchEffect: typeof import('vue')['watchEffect']
|
||||
const watchOnce: typeof import('@vueuse/core')['watchOnce']
|
||||
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
|
||||
const whenever: typeof import('@vueuse/core')['whenever']
|
||||
}
|
||||
export {}
|
||||
37
components.d.ts
vendored
Normal file
37
components.d.ts
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// 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 {
|
||||
AboutSection: typeof import('./src/components/AboutSection.vue')['default']
|
||||
BackToSite: typeof import('./src/components/BackToSite.vue')['default']
|
||||
DownArrowIcon: typeof import('./src/components/icons/DownArrowIcon.vue')['default']
|
||||
Education: typeof import('./src/components/Education.vue')['default']
|
||||
EducationSection: typeof import('./src/components/EducationSection.vue')['default']
|
||||
Footer: typeof import('./src/components/Footer.vue')['default']
|
||||
GithubIcon: typeof import('./src/components/icons/GithubIcon.vue')['default']
|
||||
Header: typeof import('./src/components/Header.vue')['default']
|
||||
InstagramIcon: typeof import('./src/components/icons/InstagramIcon.vue')['default']
|
||||
InterestSection: typeof import('./src/components/InterestSection.vue')['default']
|
||||
LanguageSection: typeof import('./src/components/LanguageSection.vue')['default']
|
||||
LeftArrowIcon: typeof import('./src/components/icons/LeftArrowIcon.vue')['default']
|
||||
LinkedInIcon: typeof import('./src/components/icons/LinkedInIcon.vue')['default']
|
||||
MailIcon: typeof import('./src/components/icons/MailIcon.vue')['default']
|
||||
Menu: typeof import('./src/components/Menu.vue')['default']
|
||||
MoonIcon: typeof import('./src/components/icons/MoonIcon.vue')['default']
|
||||
Project: typeof import('./src/components/Project.vue')['default']
|
||||
ProjectSection: typeof import('./src/components/ProjectSection.vue')['default']
|
||||
SectionPart: typeof import('./src/components/SectionPart.vue')['default']
|
||||
SectionTitle: typeof import('./src/components/SectionTitle.vue')['default']
|
||||
SocialList: typeof import('./src/components/SocialList.vue')['default']
|
||||
Stack: typeof import('./src/components/Stack.vue')['default']
|
||||
StackSection: typeof import('./src/components/StackSection.vue')['default']
|
||||
SunIcon: typeof import('./src/components/icons/SunIcon.vue')['default']
|
||||
TwitterIcon: typeof import('./src/components/icons/TwitterIcon.vue')['default']
|
||||
WorkExperience: typeof import('./src/components/WorkExperience.vue')['default']
|
||||
WorkSection: typeof import('./src/components/WorkSection.vue')['default']
|
||||
}
|
||||
}
|
||||
|
||||
export { }
|
||||
22
index.html
Normal file
22
index.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<!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">
|
||||
<title>Arthur Danjou - My Résumé</title>
|
||||
<meta name="description" content="Opinionated Vite Starter Template">
|
||||
</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>
|
||||
85
locales/en.yml
Normal file
85
locales/en.yml
Normal file
@@ -0,0 +1,85 @@
|
||||
back: Back to main website
|
||||
|
||||
date:
|
||||
from: From
|
||||
to: to
|
||||
in: In
|
||||
today: Today'hui
|
||||
|
||||
months:
|
||||
'01': January
|
||||
'02': Debruary
|
||||
'03': March
|
||||
'04': April
|
||||
'05': May
|
||||
'06': June
|
||||
'07': July
|
||||
'08': August
|
||||
'09': September
|
||||
10: October
|
||||
11: November
|
||||
12: December
|
||||
|
||||
about:
|
||||
title: About
|
||||
first: Je suis Arthur Danjou, un étudiant en mathématiques à la faculté des sciences de Paris-Saclay mais également un ingénieur logiciel freelance.
|
||||
Je m'intéresse beaucoup aux nouvelles technologies, au développement et à l'informatique.
|
||||
Je suis capable d'apprendre rapidement des nouvelles technologies pour répondre aux besoins des différents projets.
|
||||
Je suis toujours motivé par un défi et j'aime être bien organisé pour produire des résultats cohérents.
|
||||
Pouvoir créer un logiciel à partir de rien est une réelle source de motivation.
|
||||
second: J'adore partager mes connaissances et aider les autres. Je me renseigne beaucoup et lis beaucoup d'articles techniques pour découvrir de nouvelles fonctionnalités.
|
||||
Tant que je partage mes passions, je continuerai à faire ça.
|
||||
|
||||
footer:
|
||||
pdf: PDF version
|
||||
updated: Last updated on {date}
|
||||
copyright: © {year} Arthur Danjou - All rights reserved
|
||||
|
||||
header.job: Software Ingineer
|
||||
|
||||
interests:
|
||||
title: Interests
|
||||
content: Nouvelles technologies, développement, administration système, cloud computing, voyage, automobile, aéronautique, aérospatial, mathématiques, musculation
|
||||
|
||||
projects:
|
||||
title: Projects
|
||||
more: See more projects
|
||||
|
||||
stacks:
|
||||
title: Stack
|
||||
languages: Languages
|
||||
devops: DevOps
|
||||
frontend: FrontEnd
|
||||
backend: BackEnd
|
||||
|
||||
languages:
|
||||
title: Languages
|
||||
content: <strong>French</strong> (Native Speaker), <strong>English</strong> (Fluent)
|
||||
|
||||
works:
|
||||
title: Work experiences
|
||||
|
||||
autoentrepreneur:
|
||||
title: FullStack Web et Software Development
|
||||
content: Développement, conception et illustration de projets informatiques personnels. Apprentissage de nouvelles technologies et langages de programmation
|
||||
erisium:
|
||||
title: Junior Developer
|
||||
content: Développement et réalisation de projets informatiques conçus par l’équipe de Design. Maintien et mise à jour de projets en production. Correction de bugs présents
|
||||
idemia:
|
||||
title: Stage d'observation
|
||||
content: Découverte du secteur IT, technologie de l’information et du Datacenter. Découverte de différents métiers de la société
|
||||
lsam:
|
||||
title: Stage de découverte
|
||||
content: Nettoyage et préparation de la salle, accueil des clients, prise de commandes et services en salle
|
||||
|
||||
educations:
|
||||
title: Educations
|
||||
tb: Mention Très Bien
|
||||
b: Mention Bien
|
||||
|
||||
license: Licence de Mathématiques
|
||||
baccalaureate: Baccalauréat Général spécialités Mathématiques et Physique-Chimie
|
||||
dnb: Diplôme National du Brevet
|
||||
selftaught:
|
||||
title: Apprentissage en autodidacte
|
||||
content: Apprentissage de langages de programmation (TypeScript, Rust, Java, Python...) et de technologies
|
||||
90
locales/fr.yml
Normal file
90
locales/fr.yml
Normal file
@@ -0,0 +1,90 @@
|
||||
back: Retour au site principal
|
||||
|
||||
date:
|
||||
from: De
|
||||
to: à
|
||||
in: En
|
||||
today: Aujourd'hui
|
||||
|
||||
months:
|
||||
'01': Janvier
|
||||
'02': Février
|
||||
'03': Mars
|
||||
'04': Avril
|
||||
'05': Mai
|
||||
'06': Juin
|
||||
'07': Juillet
|
||||
'08': Août
|
||||
'09': Septembre
|
||||
10: Octobre
|
||||
11: Novembre
|
||||
12: Décembre
|
||||
|
||||
about:
|
||||
title: A propos
|
||||
first: Je suis Arthur Danjou, un étudiant en mathématiques à la faculté des sciences de Paris-Saclay mais également un ingénieur logiciel freelance.
|
||||
Je m'intéresse beaucoup aux nouvelles technologies, au développement et à l'informatique.
|
||||
Je suis capable d'apprendre rapidement des nouvelles technologies pour répondre aux besoins des différents projets.
|
||||
Je suis toujours motivé par un défi et j'aime être bien organisé pour produire des résultats cohérents.
|
||||
Pouvoir créer un logiciel à partir de rien est une réelle source de motivation.
|
||||
second: J'adore partager mes connaissances et aider les autres. Je me renseigne beaucoup et lis beaucoup d'articles techniques pour découvrir de nouvelles fonctionnalités.
|
||||
Tant que je partage mes passions, je continuerai à faire ça.
|
||||
|
||||
footer:
|
||||
pdf: version PDF
|
||||
updated: Dernière mise à jour le {date}
|
||||
copyright: © {year} Arthur Danjou - Tous droits réservés
|
||||
|
||||
header.job: Ingénieur Logiciel
|
||||
|
||||
interests:
|
||||
title: Intérêts
|
||||
content: Nouvelles technologies, développement, administration système, cloud computing, voyage, automobile, aéronautique, aérospatial, mathématiques, musculation
|
||||
|
||||
projects:
|
||||
title: Projets
|
||||
more: Voir plus de projets
|
||||
|
||||
ares: Site web personnel créant un unique point de contact
|
||||
athena: API connectée à des services comme Spotify fournissant diverses informations
|
||||
linkyjs: Raccourcisseur d'URL Open-Source pour les développeurs
|
||||
slidev: Traduction de la documentation en Français
|
||||
|
||||
stacks:
|
||||
title: Stack technique
|
||||
languages: Langages
|
||||
devops: DevOps
|
||||
frontend: FrontEnd
|
||||
backend: BackEnd
|
||||
|
||||
languages:
|
||||
title: Langues
|
||||
content: <strong>Francais</strong> (Langue natale), <strong>Anglais</strong> (Langue courante)
|
||||
|
||||
works:
|
||||
title: Expériences professionnelles
|
||||
|
||||
autoentrepreneur:
|
||||
title: Développement FullStack Web et Logiciel
|
||||
content: Développement, conception et illustration de projets informatiques personnels. Apprentissage de nouvelles technologies et langages de programmation
|
||||
erisium:
|
||||
title: Développeur Junior
|
||||
content: Développement et réalisation de projets informatiques conçus par l’équipe de Design. Maintien et mise à jour de projets en production. Correction de bugs présents
|
||||
idemia:
|
||||
title: Stage d'observation
|
||||
content: Découverte du secteur IT, technologie de l’information et du Datacenter. Découverte de différents métiers de la société
|
||||
lsam:
|
||||
title: Stage de découverte
|
||||
content: Nettoyage et préparation de la salle, accueil des clients, prise de commandes et services en salle
|
||||
|
||||
educations:
|
||||
title: Formations
|
||||
tb: Mention Très Bien
|
||||
b: Mention Bien
|
||||
|
||||
license: Licence de Mathématiques
|
||||
baccalaureate: Baccalauréat Général spécialités Mathématiques et Physique-Chimie
|
||||
dnb: Diplôme National du Brevet
|
||||
selftaught:
|
||||
title: Apprentissage en autodidacte
|
||||
content: Apprentissage de langages de programmation (TypeScript, Rust, Java, Python...) et de technologies
|
||||
35
package.json
Normal file
35
package.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --port 3333 --open --host",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"lint": "eslint . --ext=.ts,.vue",
|
||||
"test": "vitest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vueuse/core": "^7.7.0",
|
||||
"@vueuse/head": "^0.7.5",
|
||||
"sass": "^1.49.9",
|
||||
"vue": "^3.2.31",
|
||||
"vue-i18n": "^9.1.9",
|
||||
"vue-router": "^4.0.12",
|
||||
"windicss": "^3.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^0.16.1",
|
||||
"@intlify/vite-plugin-vue-i18n": "^3.3.1",
|
||||
"@types/node": "^17.0.21",
|
||||
"@vitejs/plugin-vue": "^2.2.2",
|
||||
"@vue/test-utils": "^2.0.0-rc.18",
|
||||
"eslint": "^8.10.0",
|
||||
"jsdom": "^19.0.0",
|
||||
"typescript": "^4.5.5",
|
||||
"unplugin-auto-import": "^0.6.1",
|
||||
"unplugin-vue-components": "^0.17.11",
|
||||
"vite": "^2.8.4",
|
||||
"vite-plugin-pages": "^0.21.0",
|
||||
"vite-plugin-windicss": "^1.8.1",
|
||||
"vitest": "^0.5.8"
|
||||
}
|
||||
}
|
||||
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 |
2
public/robots.txt
Normal file
2
public/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
31
src/App.vue
Normal file
31
src/App.vue
Normal file
@@ -0,0 +1,31 @@
|
||||
<script setup>
|
||||
import { useHead } from '@vueuse/head'
|
||||
|
||||
useHead({
|
||||
title: 'Arthur Danjou - My Résumé',
|
||||
meta: [
|
||||
{ name: 'description', content: 'See my technology resume' },
|
||||
],
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="px-4 lg:px-32 dark:text-white lg:flex py-8 lg:py-16">
|
||||
<Menu />
|
||||
<section class="lg:w-1/4 flex flex-col">
|
||||
<BackToSite />
|
||||
<Header />
|
||||
<SocialList />
|
||||
</section>
|
||||
<section class="lg:w-3/4 mt-4 lg:mt-0">
|
||||
<AboutSection />
|
||||
<WorkSection />
|
||||
<EducationSection />
|
||||
<StackSection />
|
||||
<ProjectSection />
|
||||
<InterestSection />
|
||||
<LanguageSection />
|
||||
<Footer />
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
16
src/components/AboutSection.vue
Normal file
16
src/components/AboutSection.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<SectionTitle title="about.title" />
|
||||
<SectionPart>
|
||||
<p class="text-justify leading-6">
|
||||
{{ t('about.first') }}
|
||||
<br><br>
|
||||
{{ t('about.second') }}
|
||||
</p>
|
||||
</SectionPart>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
13
src/components/BackToSite.vue
Normal file
13
src/components/BackToSite.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<a href="https://arthurdanjou.fr" target="_blank" class="flex items-center mb-4 text-gray-700 dark:text-gray-300 text-sm">
|
||||
<div class="group cursor-pointer flex items-center">
|
||||
<LeftArrowIcon class="mr-2 group-hover:-translate-x-2 duration-300 transform" /> {{ t('back') }}
|
||||
</div>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
50
src/components/Education.vue
Normal file
50
src/components/Education.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<h1 class="text-lg leading-5">
|
||||
<strong>{{ t(title) }}</strong>, {{ location }}
|
||||
</h1>
|
||||
<h3 class="my-1 text-sm text-gray-500 dark:text-gray-400">
|
||||
{{ t('date.from') }} {{ getBeginDate }} {{ t('date.to') }} {{ getEndDate }}
|
||||
</h3>
|
||||
</div>
|
||||
<p class="text-justify text-md leading-5 dark:text-gray-300">
|
||||
<slot />
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: 'Title',
|
||||
},
|
||||
location: {
|
||||
type: String,
|
||||
default: 'Location',
|
||||
},
|
||||
beginDate: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
endDate: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const getEndDate = computed(() => {
|
||||
return props.endDate === 'Today'
|
||||
? t('date.today')
|
||||
: `${t(`months.${props.endDate.split('/')[0]}`)} ${props.endDate.split('/')[1]}`
|
||||
})
|
||||
|
||||
const getBeginDate = computed(() => {
|
||||
return `${t(`months.${props.beginDate.split('/')[0]}`)} ${props.beginDate.split('/')[1]}`
|
||||
})
|
||||
</script>
|
||||
41
src/components/EducationSection.vue
Normal file
41
src/components/EducationSection.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<SectionTitle title="educations.title" />
|
||||
<SectionPart class="space-y-4">
|
||||
<Education
|
||||
title="educations.license"
|
||||
location="Faculté des Sciences de l'Université Paris-Saclay, Orsay (France)"
|
||||
begin-date="08/2021"
|
||||
end-date="Today"
|
||||
/>
|
||||
<Education
|
||||
title="educations.selftaught.title"
|
||||
location="Remote"
|
||||
begin-date="08/2021"
|
||||
end-date="Today"
|
||||
>
|
||||
{{ t('educations.selftaught.content') }}
|
||||
</Education>
|
||||
<Education
|
||||
title="educations.baccalaureate"
|
||||
location="Lycée La Salle Passy-Buzenval, Rueil-Malmaison (France)"
|
||||
begin-date="09/2020"
|
||||
end-date="09/2021"
|
||||
>
|
||||
{{ t('educations.b') }}
|
||||
</Education>
|
||||
<Education
|
||||
title="educations.dnb"
|
||||
location="Collège La Salle Passy-Buzenval, Rueil-Malmaison (France)"
|
||||
begin-date="09/2017"
|
||||
end-date="09/2018"
|
||||
>
|
||||
{{ t('educations.tb') }}
|
||||
</Education>
|
||||
</SectionPart>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
28
src/components/Footer.vue
Normal file
28
src/components/Footer.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<div class="mt-8 text-center">
|
||||
<a class="leading-5 font-bold border-b-2 hover:(border-gray-700 dark:border-white) border-gray-300 dark:border-gray-700 dark:border-gray-800 duration-300 cursor-pointer">
|
||||
{{ t('footer.pdf') }}
|
||||
</a>
|
||||
<p class="text-xs text-gray-700 dark:text-gray-300 mt-4">
|
||||
{{ t('footer.updated', {date: updated}) }}
|
||||
</p>
|
||||
<p class="text-xs text-gray-700 dark:text-gray-300 mt-1">
|
||||
{{ t('footer.copyright', {year}) }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t, locale } = useI18n()
|
||||
const year = computed(() => {
|
||||
return new Date().getFullYear()
|
||||
})
|
||||
|
||||
const updated = computed(() => {
|
||||
return locale.value === 'fr'
|
||||
? '28 Février 2022 à 16h22'
|
||||
: 'February 28th 2022 at 16:22'
|
||||
})
|
||||
</script>
|
||||
19
src/components/Header.vue
Normal file
19
src/components/Header.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<div class="my-4 text-center sm:text-left">
|
||||
<h1 class="font-black text-2xl">
|
||||
Arthur DANJOU
|
||||
</h1>
|
||||
<h2 class="text-lg text-gray-600 dark:text-gray-400">
|
||||
{{ t('header.job') }}
|
||||
</h2>
|
||||
<h3 class="text-sm text-gray-500 dark:text-gray-300 mt-2">
|
||||
Paris, France
|
||||
</h3>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
14
src/components/InterestSection.vue
Normal file
14
src/components/InterestSection.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<SectionTitle title="interests.title" />
|
||||
<SectionPart>
|
||||
<p class="text-justify">
|
||||
{{ t('interests.content') }}
|
||||
</p>
|
||||
</SectionPart>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
12
src/components/LanguageSection.vue
Normal file
12
src/components/LanguageSection.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<SectionTitle title="languages.title" />
|
||||
<SectionPart>
|
||||
<p v-html="t('languages.content')" />
|
||||
</SectionPart>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
57
src/components/Menu.vue
Normal file
57
src/components/Menu.vue
Normal file
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div class="fixed top-2 right-1 sm:(top-4 right-4) grid grid-rows-2 gap-y-2 text-center">
|
||||
<div
|
||||
class="p-1 hover:bg-gray-300 dark:hover:bg-gray-800 duration-300 cursor-pointer rounded-full"
|
||||
@click.prevent="toggleDark"
|
||||
>
|
||||
<SunIcon v-if="isDark" />
|
||||
<MoonIcon v-else />
|
||||
</div>
|
||||
<div
|
||||
class="p-1 hover:bg-gray-300 dark:hover:bg-gray-800 duration-300 cursor-pointer rounded-full transform"
|
||||
:class="{'rotate-180': scrollPosition > 100}"
|
||||
@click.prevent="teleport"
|
||||
>
|
||||
<DownArrowIcon />
|
||||
</div>
|
||||
<div @click.prevent="switchLanguage">
|
||||
<div v-if="locale === 'fr'" class="text-right text-xl px-1 hover:bg-gray-300 dark:hover:bg-gray-800 duration-300 cursor-pointer rounded-full">
|
||||
🇬🇧
|
||||
</div>
|
||||
<div v-else class="text-right text-xl px-1 hover:bg-gray-300 dark:hover:bg-gray-800 duration-300 cursor-pointer rounded-full">
|
||||
🇫🇷
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { isDark, toggleDark } from '~/composables'
|
||||
|
||||
const { locale } = useI18n()
|
||||
|
||||
const switchLanguage = () => {
|
||||
locale.value = locale.value === 'fr' ? 'en' : 'fr'
|
||||
}
|
||||
|
||||
const scrollPosition = ref(0)
|
||||
|
||||
const teleport = () => {
|
||||
window.scroll({
|
||||
behavior: 'smooth',
|
||||
top: scrollPosition.value > 100 ? 0 : document.body.scrollHeight,
|
||||
})
|
||||
}
|
||||
|
||||
const updateScroll = () => {
|
||||
scrollPosition.value = window.scrollY
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('scroll', updateScroll)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('scroll', updateScroll)
|
||||
})
|
||||
</script>
|
||||
35
src/components/Project.vue
Normal file
35
src/components/Project.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<a
|
||||
class="w-full h-full"
|
||||
:href="url"
|
||||
target="_blank"
|
||||
>
|
||||
<div class="w-full h-full p-2 border-2 rounded-lg border-white hover:border-gray-300 duration-500 cursor-pointer">
|
||||
|
||||
<h1 class="font-bold">
|
||||
{{ title }}
|
||||
</h1>
|
||||
<h2 class="text-gray-700 text-justify dark:text-gray-200">
|
||||
{{ t(description) }}
|
||||
</h2>
|
||||
</div>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
40
src/components/ProjectSection.vue
Normal file
40
src/components/ProjectSection.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<SectionTitle title="projects.title" />
|
||||
<SectionPart>
|
||||
<div class="grid gris-cols-1 sm:grid-cols-2 gap-x-8 gap-y-4 mb-4">
|
||||
<Project
|
||||
title="Ares"
|
||||
description="projects.ares"
|
||||
url="https://arthurdanjou.fr"
|
||||
/>
|
||||
<Project
|
||||
title="Athena"
|
||||
description="projects.athena"
|
||||
url="https://api.arthurdanjou.fr"
|
||||
/>
|
||||
<Project
|
||||
title="LinkyJs"
|
||||
description="projects.linkyjs"
|
||||
/>
|
||||
<Project
|
||||
title="Slidev"
|
||||
description="projects.slidev"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex justify-center sm:justify-start">
|
||||
<a
|
||||
href="https://arthurdanjou.fr/projects"
|
||||
target="_blank"
|
||||
class="leading-5 font-bold border-b-2 hover:(border-gray-700 dark:border-white) border-gray-300 dark:border-gray-700 dark:border-gray-800 duration-300 cursor-pointer"
|
||||
>
|
||||
{{ t('projects.more') }}
|
||||
</a>
|
||||
</div>
|
||||
</SectionPart>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
5
src/components/SectionPart.vue
Normal file
5
src/components/SectionPart.vue
Normal file
@@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<div class="p-6">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
19
src/components/SectionTitle.vue
Normal file
19
src/components/SectionTitle.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<h3>
|
||||
<span class="pl-1 pr-4 title py-1 font-bold text-xl relative bg-black text-white dark:(bg-white text-black)">{{ t(title) }}</span>
|
||||
</h3>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
defineProps({
|
||||
title: {
|
||||
default: 'Title',
|
||||
required: true,
|
||||
type: String,
|
||||
},
|
||||
})
|
||||
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
41
src/components/SocialList.vue
Normal file
41
src/components/SocialList.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="flex justify-center sm:justify-start">
|
||||
<div class="flex space-x-3 items-center">
|
||||
<a
|
||||
class="hover:bg-gray-300 dark:hover:bg-gray-800 p-1 rounded-full duration-300"
|
||||
href="mailto:contact@arthurdanjou.fr"
|
||||
target="_blank"
|
||||
>
|
||||
<MailIcon />
|
||||
</a>
|
||||
<a
|
||||
class="hover:bg-gray-300 dark:hover:bg-gray-800 p-1 rounded-full duration-300"
|
||||
href="https://github.com/arthurdanjou"
|
||||
target="_blank"
|
||||
>
|
||||
<GithubIcon />
|
||||
</a>
|
||||
<a
|
||||
class="hover:bg-gray-300 dark:hover:bg-gray-800 p-1 rounded-full duration-300"
|
||||
href="https://twitter.com/arthurdanj"
|
||||
target="_blank"
|
||||
>
|
||||
<TwitterIcon />
|
||||
</a>
|
||||
<a
|
||||
class="hover:bg-gray-300 dark:hover:bg-gray-800 p-1 rounded-full duration-300"
|
||||
href="https://www.linkedin.com/in/arthurdanjou"
|
||||
target="_blank"
|
||||
>
|
||||
<LinkedInIcon />
|
||||
</a>
|
||||
<a
|
||||
class="hover:bg-gray-300 dark:hover:bg-gray-800 p-1.5 rounded-full duration-300"
|
||||
href="https://www.instagram.com/arthur.dnj"
|
||||
target="_blank"
|
||||
>
|
||||
<InstagramIcon />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
22
src/components/Stack.vue
Normal file
22
src/components/Stack.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<div class="mb-2">
|
||||
<strong class="mr-2">{{ t(title) }}</strong><span class="dark:text-gray-200">{{ content }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
defineProps({
|
||||
title: {
|
||||
default: 'Title',
|
||||
required: true,
|
||||
},
|
||||
content: {
|
||||
default: 'Content',
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
9
src/components/StackSection.vue
Normal file
9
src/components/StackSection.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<SectionTitle title="stacks.title" />
|
||||
<SectionPart>
|
||||
<Stack title="stacks.languages" content="TypeScript, JavaScript, Python, Java, Rust" />
|
||||
<Stack title="stacks.frontend" content="VueJs, NuxtJs, WindiCss, Sass, TauriApp, ViteJs" />
|
||||
<Stack title="stacks.backend" content="AdonisJs, MariaDB, Redis, RabbitMQ" />
|
||||
<Stack title="stacks.devops" content="Git, Docker, CI/CD, Traefik" />
|
||||
</SectionPart>
|
||||
</template>
|
||||
66
src/components/WorkExperience.vue
Normal file
66
src/components/WorkExperience.vue
Normal file
@@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<h1 v-if="url" class="text-lg">
|
||||
<a
|
||||
:href="url"
|
||||
target="_blank"
|
||||
class="font-bold border-b-2 hover:(border-gray-700 dark:border-white) border-gray-300 dark:border-gray-600 dark:border-gray-800 duration-300 cursor-pointer"
|
||||
>
|
||||
{{ company }}
|
||||
</a> - <span class="text-gray-700 dark:text-gray-300">{{ t(title) }}</span>
|
||||
</h1>
|
||||
<h1 v-else class="text-lg">
|
||||
<strong>{{ company }}</strong> - <span class="text-gray-700 dark:text-gray-300">{{ t(title) }}</span>
|
||||
</h1>
|
||||
<h3 v-if="getBeginDate === getEndDate" class="text-sm text-gray-500 dark:text-gray-400 my-1">
|
||||
{{ t('date.in') }} {{ getEndDate }} <span class="mx-2">|</span> {{ location }}
|
||||
</h3>
|
||||
<h3 v-else class="text-sm text-gray-500 dark:text-gray-400 my-1">
|
||||
{{ t('date.from') }} {{ getBeginDate }} {{ t('date.to') }} {{ getEndDate }} <span class="mx-2">|</span> {{ location }}
|
||||
</h3>
|
||||
</div>
|
||||
<p class="text-justify text-md leading-5 dark:text-gray-300">
|
||||
<slot />
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
company: {
|
||||
type: String,
|
||||
},
|
||||
location: {
|
||||
type: String,
|
||||
},
|
||||
beginDate: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
endDate: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
},
|
||||
})
|
||||
|
||||
const getEndDate = computed(() => {
|
||||
return props.endDate === 'Today'
|
||||
? t('date.today')
|
||||
: `${t(`months.${props.endDate.split('/')[0]}`)} ${props.endDate.split('/')[1]}`
|
||||
})
|
||||
|
||||
const getBeginDate = computed(() => {
|
||||
return `${t(`months.${props.beginDate.split('/')[0]}`)} ${props.beginDate.split('/')[1]}`
|
||||
})
|
||||
</script>
|
||||
50
src/components/WorkSection.vue
Normal file
50
src/components/WorkSection.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<SectionTitle title="works.title" />
|
||||
<SectionPart class="space-y-4">
|
||||
<WorkExperience
|
||||
title="works.autoentrepreneur.title"
|
||||
company="ArtDanjProduction"
|
||||
begin-date="09/2015"
|
||||
end-date="Today"
|
||||
location="Rueil-Malmaison, France"
|
||||
url="https://arthurdanjou.fr"
|
||||
>
|
||||
{{ t('works.autoentrepreneur.content') }}
|
||||
</WorkExperience>
|
||||
<WorkExperience
|
||||
title="works.erisium.title"
|
||||
company="Erisium"
|
||||
begin-date="02/2019"
|
||||
end-date="11/2020"
|
||||
location="Remote"
|
||||
url="https://erisium.com"
|
||||
>
|
||||
{{ t('works.erisium.content') }}
|
||||
</WorkExperience>
|
||||
<WorkExperience
|
||||
title="works.idemia.title"
|
||||
company="Idemia"
|
||||
begin-date="06/2019"
|
||||
end-date="06/2019"
|
||||
location="Courbevoie, France"
|
||||
url="https://idemia.com"
|
||||
>
|
||||
{{ t('works.idemia.content') }}
|
||||
</WorkExperience>
|
||||
<WorkExperience
|
||||
title="works.lsam.title"
|
||||
company="La Salle à Manger"
|
||||
begin-date="04/2018"
|
||||
end-date="04/2018"
|
||||
location="Boulogne-Billancourt, France"
|
||||
>
|
||||
{{ t('works.lsam.content') }}
|
||||
</WorkExperience>
|
||||
</SectionPart>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
14
src/components/icons/DownArrowIcon.vue
Normal file
14
src/components/icons/DownArrowIcon.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<svg width="1.3em" height="1.3em" viewBox="0 0 256 256" focusable="false">
|
||||
<path
|
||||
d="M208.485 152.485l-72 72a12 12 0 0 1-16.97 0l-72-72a12 12 0 0 1 16.97-16.97L116 187.029V40a12 12 0 0 1 24 0v147.03l51.515-51.515a12 12 0 0 1 16.97 16.97z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'DownArrowIcon',
|
||||
}
|
||||
</script>
|
||||
14
src/components/icons/GithubIcon.vue
Normal file
14
src/components/icons/GithubIcon.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<svg width="1.3em" height="1.3em" viewBox="0 0 24 24" focusable="false">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M10.07 20.503a1 1 0 0 0-1.18-.983c-1.31.24-2.963.276-3.402-.958a5.708 5.708 0 0 0-1.837-2.415a1.2 1.2 0 0 1-.167-.11a1 1 0 0 0-.93-.645h-.005a1 1 0 0 0-1 .995c-.004.815.81 1.338 1.141 1.514a4.44 4.44 0 0 1 .924 1.36c.365 1.023 1.423 2.576 4.466 2.376l.003.098l.004.268a1 1 0 0 0 2 0l-.005-.318c-.005-.19-.012-.464-.012-1.182ZM20.737 5.377a5.39 5.39 0 0 0 .09-.42a6.278 6.278 0 0 0-.408-3.293a1.002 1.002 0 0 0-.615-.58c-.356-.12-1.67-.357-4.184 1.25a13.87 13.87 0 0 0-6.354 0C6.762.75 5.455.966 5.102 1.079a.997.997 0 0 0-.631.584a6.3 6.3 0 0 0-.404 3.357c.025.127.051.246.079.354a6.27 6.27 0 0 0-1.256 3.83a8.422 8.422 0 0 0 .043.921c.334 4.603 3.334 5.984 5.424 6.459a4.591 4.591 0 0 0-.118.4a1 1 0 0 0 1.942.479a1.678 1.678 0 0 1 .468-.878a1 1 0 0 0-.546-1.745c-3.454-.395-4.954-1.802-5.18-4.899a6.61 6.61 0 0 1-.033-.738a4.258 4.258 0 0 1 .92-2.713a3.022 3.022 0 0 1 .195-.231a1 1 0 0 0 .188-1.025a3.388 3.388 0 0 1-.155-.555a4.094 4.094 0 0 1 .079-1.616a7.543 7.543 0 0 1 2.415 1.18a1.009 1.009 0 0 0 .827.133a11.777 11.777 0 0 1 6.173.001a1.005 1.005 0 0 0 .83-.138a7.572 7.572 0 0 1 2.406-1.19a4.04 4.04 0 0 1 .087 1.578a3.205 3.205 0 0 1-.169.607a1 1 0 0 0 .188 1.025c.078.087.155.18.224.268A4.122 4.122 0 0 1 20 9.203a7.039 7.039 0 0 1-.038.777c-.22 3.056-1.725 4.464-5.195 4.86a1 1 0 0 0-.546 1.746a1.63 1.63 0 0 1 .466.908a3.06 3.06 0 0 1 .093.82v2.333c-.01.648-.01 1.133-.01 1.356a1 1 0 1 0 2 0c0-.217 0-.692.01-1.34v-2.35a4.881 4.881 0 0 0-.155-1.311a4.256 4.256 0 0 0-.116-.416a6.513 6.513 0 0 0 5.445-6.424A8.697 8.697 0 0 0 22 9.203a6.13 6.13 0 0 0-1.263-3.826Z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'GithubIcon',
|
||||
}
|
||||
</script>
|
||||
14
src/components/icons/InstagramIcon.vue
Normal file
14
src/components/icons/InstagramIcon.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<svg width="1.2em" height="1.2em" viewBox="0 0 16 16" focusable="false">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M8 0C5.829 0 5.556.01 4.703.048C3.85.088 3.269.222 2.76.42a3.917 3.917 0 0 0-1.417.923A3.927 3.927 0 0 0 .42 2.76C.222 3.268.087 3.85.048 4.7C.01 5.555 0 5.827 0 8.001c0 2.172.01 2.444.048 3.297c.04.852.174 1.433.372 1.942c.205.526.478.972.923 1.417c.444.445.89.719 1.416.923c.51.198 1.09.333 1.942.372C5.555 15.99 5.827 16 8 16s2.444-.01 3.298-.048c.851-.04 1.434-.174 1.943-.372a3.916 3.916 0 0 0 1.416-.923c.445-.445.718-.891.923-1.417c.197-.509.332-1.09.372-1.942C15.99 10.445 16 10.173 16 8s-.01-2.445-.048-3.299c-.04-.851-.175-1.433-.372-1.941a3.926 3.926 0 0 0-.923-1.417A3.911 3.911 0 0 0 13.24.42c-.51-.198-1.092-.333-1.943-.372C10.443.01 10.172 0 7.998 0h.003zm-.717 1.442h.718c2.136 0 2.389.007 3.232.046c.78.035 1.204.166 1.486.275c.373.145.64.319.92.599c.28.28.453.546.598.92c.11.281.24.705.275 1.485c.039.843.047 1.096.047 3.231s-.008 2.389-.047 3.232c-.035.78-.166 1.203-.275 1.485a2.47 2.47 0 0 1-.599.919c-.28.28-.546.453-.92.598c-.28.11-.704.24-1.485.276c-.843.038-1.096.047-3.232.047s-2.39-.009-3.233-.047c-.78-.036-1.203-.166-1.485-.276a2.478 2.478 0 0 1-.92-.598a2.48 2.48 0 0 1-.6-.92c-.109-.281-.24-.705-.275-1.485c-.038-.843-.046-1.096-.046-3.233c0-2.136.008-2.388.046-3.231c.036-.78.166-1.204.276-1.486c.145-.373.319-.64.599-.92c.28-.28.546-.453.92-.598c.282-.11.705-.24 1.485-.276c.738-.034 1.024-.044 2.515-.045v.002zm4.988 1.328a.96.96 0 1 0 0 1.92a.96.96 0 0 0 0-1.92zm-4.27 1.122a4.109 4.109 0 1 0 0 8.217a4.109 4.109 0 0 0 0-8.217zm0 1.441a2.667 2.667 0 1 1 0 5.334a2.667 2.667 0 0 1 0-5.334z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'InstagramIcon',
|
||||
}
|
||||
</script>
|
||||
14
src/components/icons/LeftArrowIcon.vue
Normal file
14
src/components/icons/LeftArrowIcon.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<svg width="1em" height="1em" viewBox="0 0 256 256" focusable="false">
|
||||
<path
|
||||
d="M228 128a12 12 0 0 1-12 12H68.97l51.515 51.515a12 12 0 0 1-16.97 16.97l-72-72a12 12 0 0 1 0-16.97l72-72a12 12 0 0 1 16.97 16.97L68.971 116H216a12 12 0 0 1 12 12z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'LeftArrowIcon',
|
||||
}
|
||||
</script>
|
||||
14
src/components/icons/LinkedInIcon.vue
Normal file
14
src/components/icons/LinkedInIcon.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<svg width="1.5em" height="1.5em" viewBox="0 0 24 24" focusable="false">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M19 3a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14m-.5 15.5v-5.3a3.26 3.26 0 0 0-3.26-3.26c-.85 0-1.84.52-2.32 1.3v-1.11h-2.79v8.37h2.79v-4.93c0-.77.62-1.4 1.39-1.4a1.4 1.4 0 0 1 1.4 1.4v4.93h2.79M6.88 8.56a1.68 1.68 0 0 0 1.68-1.68c0-.93-.75-1.69-1.68-1.69a1.69 1.69 0 0 0-1.69 1.69c0 .93.76 1.68 1.69 1.68m1.39 9.94v-8.37H5.5v8.37h2.77Z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'LinkedInIcon',
|
||||
}
|
||||
</script>
|
||||
14
src/components/icons/MailIcon.vue
Normal file
14
src/components/icons/MailIcon.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<svg width="1.3em" height="1.3em" viewBox="0 0 24 24" focusable="false">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10h5v-2h-5c-4.34 0-8-3.66-8-8s3.66-8 8-8s8 3.66 8 8v1.43c0 .79-.71 1.57-1.5 1.57s-1.5-.78-1.5-1.57V12c0-2.76-2.24-5-5-5s-5 2.24-5 5s2.24 5 5 5c1.38 0 2.64-.56 3.54-1.47c.65.89 1.77 1.47 2.96 1.47c1.97 0 3.5-1.6 3.5-3.57V12c0-5.52-4.48-10-10-10zm0 13c-1.66 0-3-1.34-3-3s1.34-3 3-3s3 1.34 3 3s-1.34 3-3 3z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MailIcon',
|
||||
}
|
||||
</script>
|
||||
13
src/components/icons/MoonIcon.vue
Normal file
13
src/components/icons/MoonIcon.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<svg width="1.3em" height="1.3em" viewBox="0 0 256 256" focusable="false">
|
||||
<path
|
||||
d="M228.13 149.117a12.004 12.004 0 0 0-14.962-7.952a80.032 80.032 0 0 1-98.31-98.415a12.002 12.002 0 0 0-14.919-14.917a104.014 104.014 0 1 0 128.247 128.162a12.002 12.002 0 0 0-.055-6.878zM128 208A80.01 80.01 0 0 1 88.146 58.617a103.982 103.982 0 0 0 109.237 109.237A80.31 80.31 0 0 1 128 208z" fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MoonIcon',
|
||||
}
|
||||
</script>
|
||||
13
src/components/icons/SunIcon.vue
Normal file
13
src/components/icons/SunIcon.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<svg width="1.3em" height="1.3em" viewBox="0 0 256 256" focusable="false">
|
||||
<path
|
||||
d="M128 56a72 72 0 1 0 72 72a72.081 72.081 0 0 0-72-72zm0 120a48 48 0 1 1 48-48a48.054 48.054 0 0 1-48 48zM116 28v-8a12 12 0 0 1 24 0v8a12 12 0 0 1-24 0zm74.225 37.774a12 12 0 0 1 0-16.97l5.658-5.657a12 12 0 1 1 16.97 16.971l-5.658 5.657a12 12 0 0 1-16.97 0zM248 128a12 12 0 0 1-12 12h-8a12 12 0 0 1 0-24h8a12 12 0 0 1 12 12zm-35.147 67.882a12 12 0 0 1-16.97 16.971l-5.658-5.657a12 12 0 1 1 16.97-16.97zM140 228v8a12 12 0 0 1-24 0v-8a12 12 0 0 1 24 0zm-74.225-37.775a12 12 0 0 1 0 16.97l-5.657 5.658a12 12 0 0 1-16.971-16.97l5.657-5.658a12 12 0 0 1 16.97 0zM40 128a12 12 0 0 1-12 12h-8a12 12 0 0 1 0-24h8a12 12 0 0 1 12 12zm3.147-67.882a12 12 0 1 1 16.97-16.971l5.657 5.657a12 12 0 1 1-16.97 16.97z" fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SunIcon',
|
||||
}
|
||||
</script>
|
||||
14
src/components/icons/TwitterIcon.vue
Normal file
14
src/components/icons/TwitterIcon.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<svg width="1.5em" height="1.5em" viewBox="0 0 24 24">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M15.3 5.55a2.9 2.9 0 0 0-2.9 2.847l-.028 1.575a.6.6 0 0 1-.68.583l-1.561-.212c-2.054-.28-4.022-1.226-5.91-2.799c-.598 3.31.57 5.603 3.383 7.372l1.747 1.098a.6.6 0 0 1 .034.993L7.793 18.17c.947.059 1.846.017 2.592-.131c4.718-.942 7.855-4.492 7.855-10.348c0-.478-1.012-2.141-2.94-2.141zm-4.9 2.81a4.9 4.9 0 0 1 8.385-3.355c.711-.005 1.316.175 2.669-.645c-.335 1.64-.5 2.352-1.214 3.331c0 7.642-4.697 11.358-9.463 12.309c-3.268.652-8.02-.419-9.382-1.841c.694-.054 3.514-.357 5.144-1.55C5.16 15.7-.329 12.47 3.278 3.786c1.693 1.977 3.41 3.323 5.15 4.037c1.158.475 1.442.465 1.973.538z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'RiTwitterLine',
|
||||
}
|
||||
</script>
|
||||
2
src/composables/dark.ts
Normal file
2
src/composables/dark.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export const isDark = useDark()
|
||||
export const toggleDark = useToggle(isDark)
|
||||
1
src/composables/index.ts
Normal file
1
src/composables/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './dark'
|
||||
43
src/main.ts
Normal file
43
src/main.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
// register vue composition api globally
|
||||
import { createApp } from 'vue'
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { createHead } from '@vueuse/head'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import routes from 'virtual:generated-pages'
|
||||
import App from './App.vue'
|
||||
|
||||
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 app = createApp(App)
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
})
|
||||
const head = createHead()
|
||||
|
||||
const messages = Object.fromEntries(
|
||||
Object.entries(
|
||||
import.meta.globEager('../locales/*.y(a)?ml'))
|
||||
.map(([key, value]) => {
|
||||
const yaml = key.endsWith('.yaml')
|
||||
return [key.slice(11, yaml ? -5 : -4), value.default]
|
||||
}),
|
||||
)
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
messages,
|
||||
})
|
||||
|
||||
app.use(i18n)
|
||||
app.use(router)
|
||||
app.use(head)
|
||||
app.mount('#app')
|
||||
11
src/styles/main.css
Executable file
11
src/styles/main.css
Executable file
@@ -0,0 +1,11 @@
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
background: #121212;
|
||||
}
|
||||
3
test/__snapshots__/component.test.ts.snap
Normal file
3
test/__snapshots__/component.test.ts.snap
Normal file
@@ -0,0 +1,3 @@
|
||||
// Vitest Snapshot v1
|
||||
|
||||
exports[`Counter.vue > should render 1`] = `"<div>10 <button class=\\"inc\\"> + </button><button class=\\"dec\\"> - </button></div>"`;
|
||||
5
test/basic.test.ts
Normal file
5
test/basic.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
describe('Hi', () => {
|
||||
it('should works', () => {
|
||||
expect(1 + 1).toEqual(2)
|
||||
})
|
||||
})
|
||||
20
test/component.test.ts
Normal file
20
test/component.test.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
|
||||
describe('Counter.vue', () => {
|
||||
it('should render', () => {
|
||||
const wrapper = mount(Counter, { props: { initial: 10 } })
|
||||
expect(wrapper.text()).toContain('10')
|
||||
expect(wrapper.html()).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should be interactive', async() => {
|
||||
const wrapper = mount(Counter, { props: { initial: 0 } })
|
||||
expect(wrapper.text()).toContain('0')
|
||||
|
||||
expect(wrapper.find('.inc').exists()).toBe(true)
|
||||
|
||||
await wrapper.get('button').trigger('click')
|
||||
|
||||
expect(wrapper.text()).toContain('1')
|
||||
})
|
||||
})
|
||||
25
tsconfig.json
Normal file
25
tsconfig.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"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"
|
||||
],
|
||||
"paths": {
|
||||
"~/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["dist", "node_modules"]
|
||||
}
|
||||
66
vite.config.ts
Normal file
66
vite.config.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
/// <reference types="vitest" />
|
||||
|
||||
import path from 'path'
|
||||
import { defineConfig } from 'vite'
|
||||
import Vue from '@vitejs/plugin-vue'
|
||||
import Pages from 'vite-plugin-pages'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import WindiCSS from 'vite-plugin-windicss'
|
||||
import VueI18n from '@intlify/vite-plugin-vue-i18n'
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
'~/': `${path.resolve(__dirname, 'src')}/`,
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
Vue(),
|
||||
|
||||
// https://github.com/hannoeru/vite-plugin-pages
|
||||
Pages(),
|
||||
|
||||
WindiCSS(),
|
||||
|
||||
// https://github.com/antfu/unplugin-auto-import
|
||||
AutoImport({
|
||||
imports: [
|
||||
'vue',
|
||||
'vue-router',
|
||||
'@vueuse/core',
|
||||
'@vueuse/head',
|
||||
'vitest',
|
||||
],
|
||||
dts: true,
|
||||
}),
|
||||
|
||||
// https://github.com/antfu/vite-plugin-components
|
||||
Components({
|
||||
dts: true,
|
||||
}),
|
||||
|
||||
VueI18n({
|
||||
runtimeOnly: true,
|
||||
compositionOnly: true,
|
||||
include: [path.resolve(__dirname, 'locales/**')],
|
||||
}),
|
||||
],
|
||||
|
||||
// https://github.com/vitest-dev/vitest
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
},
|
||||
|
||||
optimizeDeps: {
|
||||
include: [
|
||||
'vue',
|
||||
'vue-router',
|
||||
'@vueuse/core',
|
||||
'@vueuse/head',
|
||||
],
|
||||
exclude: [
|
||||
'vue-demi',
|
||||
],
|
||||
},
|
||||
})
|
||||
5
windi.config.ts
Normal file
5
windi.config.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { defineConfig } from 'windicss/helpers'
|
||||
|
||||
export default defineConfig({
|
||||
darkMode: 'class',
|
||||
})
|
||||
Reference in New Issue
Block a user