mirror of
https://github.com/Rakantor/personal-portfolio.git
synced 2025-12-17 11:36:32 +01:00
Migrate to Nuxt 3 and Vuetify 3
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": ["./*"],
|
||||
"@/*": ["./*"],
|
||||
"~~/*": ["./*"],
|
||||
"@@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"vueCompilerOptions": {
|
||||
"target": 2.7
|
||||
},
|
||||
"exclude": ["node_modules", ".nuxt", "dist"]
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-app dark :style="{ background: $vuetify.theme.themes[theme].background }">
|
||||
<v-app dark class="v-app-bg">
|
||||
<v-navigation-drawer
|
||||
v-model="drawer"
|
||||
:mini-variant="miniVariant"
|
||||
@@ -9,46 +9,38 @@
|
||||
color="backgroundSecondary"
|
||||
|
||||
>
|
||||
<v-list nav>
|
||||
<v-list-item-group
|
||||
v-model="selectedItem"
|
||||
color="primary"
|
||||
>
|
||||
<v-list nav :lines="false">
|
||||
<v-list-item
|
||||
v-for="(item, i) in items"
|
||||
:key="i"
|
||||
:to="item.to"
|
||||
active-color="primary"
|
||||
router
|
||||
exact
|
||||
>
|
||||
<v-list-item-action>
|
||||
<v-icon>{{ item.icon }}</v-icon>
|
||||
</v-list-item-action>
|
||||
<v-list-item-content>
|
||||
<template v-slot:prepend>
|
||||
<v-icon :icon="item.icon"></v-icon>
|
||||
</template>
|
||||
<v-list-item-title v-text="item.title" />
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list-item-group>
|
||||
</v-list>
|
||||
<template #append>
|
||||
<div class="pa-2">
|
||||
<v-btn block outlined color="primary" :href="`mailto:${myName}<${myEmail}>`">
|
||||
<v-icon left>mdi-email-outline</v-icon>
|
||||
<v-btn block outlined color="primary" prepend-icon="mdi-email-outline" :href="`mailto:${myName}<${myEmail}>`">
|
||||
Contact
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
</v-navigation-drawer>
|
||||
<v-app-bar fixed flat app color="transparent">
|
||||
<v-avatar size="48" color="backgroundSecondary" class="mr-3" style="cursor: pointer" @click.native="$router.push('/')">
|
||||
<img
|
||||
src="@/assets/avatar_transparent.png"
|
||||
alt="Manuel"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<v-avatar size="48" color="backgroundSecondary" style="cursor: pointer" @click.native="$router.push('/')">
|
||||
<img src="~/assets/avatar_transparent.png" width="55" />
|
||||
</v-avatar>
|
||||
<v-toolbar-title class="text-subtitle-1" v-text="myName" />
|
||||
</template>
|
||||
<v-app-bar-title class="text-subtitle-1" v-text="myName" />
|
||||
<v-spacer />
|
||||
<v-app-bar-nav-icon v-if="$vuetify.breakpoint.smAndDown" @click.stop="drawer = !drawer" />
|
||||
<v-app-bar-nav-icon v-if="smAndDown" @click.stop="drawer = !drawer" />
|
||||
<div v-else>
|
||||
<v-btn plain active-class="link-active" to="/">Home</v-btn>
|
||||
<v-btn plain active-class="link-active" to="/bio">About</v-btn>
|
||||
@@ -58,7 +50,7 @@
|
||||
</v-app-bar>
|
||||
<v-main>
|
||||
<v-container class="my-16">
|
||||
<Nuxt />
|
||||
<slot />
|
||||
</v-container>
|
||||
</v-main>
|
||||
<v-footer app absolute color="transparent">
|
||||
@@ -73,8 +65,14 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useDisplay } from 'vuetify'
|
||||
|
||||
export default {
|
||||
name: 'DefaultLayout',
|
||||
setup () {
|
||||
const { smAndDown } = useDisplay()
|
||||
return { smAndDown }
|
||||
},
|
||||
data: () => ({
|
||||
drawer: false,
|
||||
miniVariant: false,
|
||||
@@ -98,20 +96,18 @@ export default {
|
||||
to: '/portfolio',
|
||||
}
|
||||
]
|
||||
}),
|
||||
computed: {
|
||||
theme () {
|
||||
return (this.$vuetify.theme.dark) ? 'dark' : 'light'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.v-app-bg {
|
||||
background: rgb(var(--v-theme-background))
|
||||
}
|
||||
.link-active {
|
||||
color: var(--v-primary-base);
|
||||
}
|
||||
.v-btn--plain >>> .v-btn__content {
|
||||
.v-btn--plain:deep(.v-btn__content) {
|
||||
color: inherit;
|
||||
transition: all 0.28s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
100
nuxt.config.js
100
nuxt.config.js
@@ -1,100 +0,0 @@
|
||||
import colors from 'vuetify/es5/util/colors'
|
||||
|
||||
export default {
|
||||
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
|
||||
ssr: false,
|
||||
|
||||
// Target: https://go.nuxtjs.dev/config-target
|
||||
target: 'static',
|
||||
|
||||
// Global page headers: https://go.nuxtjs.dev/config-head
|
||||
head: {
|
||||
titleTemplate: '%s | Home',
|
||||
title: 'Manuel',
|
||||
htmlAttrs: {
|
||||
lang: 'en',
|
||||
},
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
||||
{ hid: 'description', name: 'description', content: '' },
|
||||
{ name: 'format-detection', content: 'telephone=no' },
|
||||
],
|
||||
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
|
||||
},
|
||||
|
||||
// Global CSS: https://go.nuxtjs.dev/config-css
|
||||
css: [],
|
||||
|
||||
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
|
||||
plugins: [],
|
||||
|
||||
// Auto import components: https://go.nuxtjs.dev/config-components
|
||||
components: true,
|
||||
|
||||
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
|
||||
buildModules: [
|
||||
// https://go.nuxtjs.dev/eslint
|
||||
'@nuxtjs/eslint-module',
|
||||
// https://go.nuxtjs.dev/vuetify
|
||||
'@nuxtjs/vuetify',
|
||||
],
|
||||
|
||||
// Modules: https://go.nuxtjs.dev/config-modules
|
||||
modules: [
|
||||
// https://go.nuxtjs.dev/axios
|
||||
'@nuxtjs/axios',
|
||||
],
|
||||
|
||||
// Axios module configuration: https://go.nuxtjs.dev/config-axios
|
||||
axios: {
|
||||
// Workaround to avoid enforcing hard-coded localhost:3000: https://github.com/nuxt-community/axios-module/issues/308
|
||||
baseURL: '/',
|
||||
},
|
||||
|
||||
// Vuetify module configuration: https://go.nuxtjs.dev/config-vuetify
|
||||
vuetify: {
|
||||
customVariables: ['~/assets/variables.scss'],
|
||||
theme: {
|
||||
options: { customProperties: true },
|
||||
dark: true,
|
||||
themes: {
|
||||
dark: {
|
||||
background: '#0A192F',
|
||||
backgroundSecondary: '#112240',
|
||||
primary: '#64FFDA',
|
||||
accent: colors.grey.darken3,
|
||||
secondary: colors.amber.darken3,
|
||||
info: colors.teal.lighten1,
|
||||
warning: colors.amber.base,
|
||||
error: colors.deepOrange.accent4,
|
||||
success: colors.green.accent3,
|
||||
},
|
||||
// Bert
|
||||
/*dark: {
|
||||
background: '#0B0C10',
|
||||
primary: '#66FCF1',
|
||||
accent: colors.grey.darken3,
|
||||
secondary: colors.amber.darken3,
|
||||
info: colors.teal.lighten1,
|
||||
warning: colors.amber.base,
|
||||
error: colors.deepOrange.accent4,
|
||||
success: colors.green.accent3,
|
||||
},
|
||||
// Nuxt Default
|
||||
dark: {
|
||||
primary: colors.blue.darken2,
|
||||
accent: colors.grey.darken3,
|
||||
secondary: colors.amber.darken3,
|
||||
info: colors.teal.lighten1,
|
||||
warning: colors.amber.base,
|
||||
error: colors.deepOrange.accent4,
|
||||
success: colors.green.accent3,
|
||||
},*/
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Build Configuration: https://go.nuxtjs.dev/config-build
|
||||
build: {},
|
||||
}
|
||||
55
nuxt.config.ts
Normal file
55
nuxt.config.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import vuetify from 'vite-plugin-vuetify'
|
||||
|
||||
// https://v3.nuxtjs.org/api/configuration/nuxt.config
|
||||
export default defineNuxtConfig({
|
||||
ssr: false,
|
||||
|
||||
css: ['vuetify/styles'],
|
||||
|
||||
vite: {
|
||||
ssr: {
|
||||
noExternal: ['vuetify'] // add the vuetify vite plugin
|
||||
}
|
||||
},
|
||||
|
||||
build: {
|
||||
transpile: ['vuetify']
|
||||
},
|
||||
|
||||
publicRuntimeConfig: {
|
||||
axios: {
|
||||
baseURL: '/',
|
||||
},
|
||||
},
|
||||
|
||||
app: {
|
||||
head: {
|
||||
titleTemplate: '%s | Home',
|
||||
title: 'Manuel',
|
||||
htmlAttrs: {
|
||||
lang: 'en',
|
||||
},
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
||||
{ hid: 'description', name: 'description', content: '' },
|
||||
{ name: 'format-detection', content: 'telephone=no' },
|
||||
],
|
||||
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
|
||||
}
|
||||
},
|
||||
|
||||
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
|
||||
plugins: [],
|
||||
|
||||
// Modules: https://go.nuxtjs.dev/config-modules
|
||||
modules: [
|
||||
// https://go.nuxtjs.dev/axios
|
||||
// ['@nuxtjs/axios', { proxyHeaders: false }],
|
||||
// this adds the vuetify vite plugin
|
||||
// also produces type errors in the current beta release
|
||||
async (options, nuxt) => {
|
||||
nuxt.hooks.hook('vite:extendConfig', config => config.plugins.push(vuetify()))
|
||||
}
|
||||
]
|
||||
})
|
||||
33228
package-lock.json
generated
33228
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
34
package.json
34
package.json
@@ -3,35 +3,21 @@
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt start",
|
||||
"dev": "nuxt dev",
|
||||
"generate": "nuxt generate",
|
||||
"lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .",
|
||||
"lint:prettier": "prettier --check .",
|
||||
"lint": "npm run lint:js && npm run lint:prettier",
|
||||
"lintfix": "prettier --write --list-different . && npm run lint:js -- --fix"
|
||||
"preview": "nuxt preview",
|
||||
"postinstall": "nuxt prepare"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@mdi/font": "^7.0.96",
|
||||
"nuxt": "3.0.0-rc.13"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxtjs/axios": "^5.13.6",
|
||||
"core-js": "^3.19.3",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nuxt": "^2.15.8",
|
||||
"vue": "^2.6.14",
|
||||
"vue-server-renderer": "^2.6.14",
|
||||
"vue-template-compiler": "^2.6.14",
|
||||
"vuetify": "^2.6.1",
|
||||
"webpack": "^4.46.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^7.16.3",
|
||||
"@nuxtjs/eslint-config": "^8.0.0",
|
||||
"@nuxtjs/eslint-module": "^3.0.2",
|
||||
"@nuxtjs/vuetify": "^1.12.3",
|
||||
"eslint": "^8.4.1",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-nuxt": "^3.1.0",
|
||||
"eslint-plugin-vue": "^8.2.0",
|
||||
"prettier": "^2.5.1"
|
||||
"sass": "^1.56.0",
|
||||
"vite-plugin-vuetify": "^1.0.0",
|
||||
"vuetify": "^3.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,29 +11,19 @@
|
||||
</span>
|
||||
</v-col>
|
||||
<v-col v-for="set, ind in sets" :key="ind" cols="12">
|
||||
<v-tooltip v-for="(value, index) in set" :key="index" bottom>
|
||||
<template #activator="{ on, attrs }">
|
||||
<v-tooltip v-for="(value, index) in set" :key="index" location="bottom" :text="value.title">
|
||||
<template #activator="{ props }">
|
||||
<v-btn
|
||||
:small="value.level == 1"
|
||||
:large="value.level == 2"
|
||||
:x-large="value.level >= 3"
|
||||
icon
|
||||
variant="text"
|
||||
:size="getButtonSize(value.level)"
|
||||
:icon="value.icon"
|
||||
color="primary"
|
||||
class="mx-1"
|
||||
:href="`https://${value.url}`"
|
||||
target="_blank"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
>
|
||||
<v-icon
|
||||
color="primary"
|
||||
:large="value.level == 2"
|
||||
:x-large="value.level >= 3"
|
||||
>
|
||||
{{ value.icon }}
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
v-bind="props"
|
||||
/>
|
||||
</template>
|
||||
<span>{{ value.title }}</span>
|
||||
</v-tooltip>
|
||||
</v-col>
|
||||
</v-row>
|
||||
@@ -88,6 +78,15 @@ export default {
|
||||
skills () {
|
||||
return [...this.languages, ...this.frameworks, ...this.tech, ...this.os]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getButtonSize (level) {
|
||||
switch (level) {
|
||||
case 1: return 'small'
|
||||
case 2: return 'large'
|
||||
default: return 'x-large'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-row justify="center" align="center">
|
||||
<v-row justify="center">
|
||||
<v-col cols="12">
|
||||
<span class="text-h3">Hi, my name is Manuel.</span>
|
||||
</v-col>
|
||||
@@ -7,8 +7,7 @@
|
||||
<span class="text-h6">I'm a Software Developer based in Vienna, Austria.<br/>I make all kind of applications.</span>
|
||||
</v-col>
|
||||
<v-col cols="12">
|
||||
<v-btn depressed outlined color="primary" href="mailto:rakantor.dev@gmail.com">
|
||||
<v-icon left>mdi-email-outline</v-icon>
|
||||
<v-btn depressed outlined color="primary" prepend-icon="mdi-email-outline" href="mailto:rakantor.dev@gmail.com">
|
||||
Contact me
|
||||
</v-btn>
|
||||
</v-col>
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<v-col v-for="(project, index) of projects" :key="index" cols="12" md="6">
|
||||
<v-card color="backgroundSecondary">
|
||||
<v-img
|
||||
height="250"
|
||||
src="https://cdn.vuetifyjs.com/images/cards/cooking.png"
|
||||
cover
|
||||
></v-img>
|
||||
<v-card-title>
|
||||
<span v-if="project.projectUrl">
|
||||
@@ -23,20 +23,16 @@
|
||||
<v-card-actions>
|
||||
<v-btn
|
||||
v-if="project.repoUrl"
|
||||
icon
|
||||
icon="mdi-github"
|
||||
:href="`https://${project.repoUrl}`"
|
||||
target="_blank"
|
||||
>
|
||||
<v-icon>mdi-github</v-icon>
|
||||
</v-btn>
|
||||
/>
|
||||
<v-btn
|
||||
v-if="project.projectUrl"
|
||||
icon
|
||||
icon="mdi-open-in-new"
|
||||
:href="`https://${project.projectUrl}`"
|
||||
target="_blank"
|
||||
>
|
||||
<v-icon>mdi-open-in-new</v-icon>
|
||||
</v-btn>
|
||||
/>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-col>
|
||||
@@ -71,6 +67,7 @@ export default {
|
||||
subtitle: 'Nuxt.js Web App',
|
||||
description: 'Android (Java) Firebase',
|
||||
repoUrl: 'github.com/Rakantor/iu-quiz-app',
|
||||
projectUrl: 'iu-quiz-app.web.app'
|
||||
},
|
||||
{
|
||||
title: 'Menacing Blue',
|
||||
|
||||
57
plugins/vuetify.ts
Normal file
57
plugins/vuetify.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { createVuetify, ThemeDefinition } from 'vuetify'
|
||||
import * as components from 'vuetify/components'
|
||||
import * as directives from 'vuetify/directives'
|
||||
import '@mdi/font/css/materialdesignicons.css'
|
||||
|
||||
const myCustomDarkTheme: ThemeDefinition = {
|
||||
dark: true,
|
||||
colors: {
|
||||
background: '#0A192F',
|
||||
backgroundSecondary: '#112240',
|
||||
primary: '#64FFDA',
|
||||
/* accent: colors.grey.darken3,
|
||||
secondary: colors.amber.darken3,
|
||||
info: colors.teal.lighten1,
|
||||
warning: colors.amber.base,
|
||||
error: colors.deepOrange.accent4,
|
||||
success: colors.green.accent3 */
|
||||
}
|
||||
// Bert
|
||||
/* dark: {
|
||||
background: '#0B0C10',
|
||||
primary: '#66FCF1',
|
||||
accent: colors.grey.darken3,
|
||||
secondary: colors.amber.darken3,
|
||||
info: colors.teal.lighten1,
|
||||
warning: colors.amber.base,
|
||||
error: colors.deepOrange.accent4,
|
||||
success: colors.green.accent3,
|
||||
},
|
||||
// Nuxt Default
|
||||
dark: {
|
||||
primary: colors.blue.darken2,
|
||||
accent: colors.grey.darken3,
|
||||
secondary: colors.amber.darken3,
|
||||
info: colors.teal.lighten1,
|
||||
warning: colors.amber.base,
|
||||
error: colors.deepOrange.accent4,
|
||||
success: colors.green.accent3,
|
||||
}, */
|
||||
}
|
||||
|
||||
export default defineNuxtPlugin(nuxtApp => {
|
||||
const vuetify = createVuetify({
|
||||
components,
|
||||
directives,
|
||||
theme: {
|
||||
// customVariables: ['~/assets/variables.scss'],
|
||||
defaultTheme: 'myCustomDarkTheme',
|
||||
// options: { customProperties: true },
|
||||
themes: {
|
||||
myCustomDarkTheme,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
nuxtApp.vueApp.use(vuetify)
|
||||
})
|
||||
4
tsconfig.json
Normal file
4
tsconfig.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
// https://v3.nuxtjs.org/concepts/typescript
|
||||
"extends": "./.nuxt/tsconfig.json"
|
||||
}
|
||||
Reference in New Issue
Block a user