Skip to content

Commit

Permalink
Merge pull request #275 from JonathanBout/master
Browse files Browse the repository at this point in the history
Repair eslint, apply it's warnings and separate backend into a separate file
  • Loading branch information
JonathanBout authored Oct 10, 2024
2 parents 748736b + ae31d85 commit fa634e9
Show file tree
Hide file tree
Showing 26 changed files with 393 additions and 540 deletions.
15 changes: 0 additions & 15 deletions .eslintrc.cjs

This file was deleted.

4 changes: 3 additions & 1 deletion env.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
/// <reference types="vite/client" />
/// <reference path="module.d.ts" />

import "module"

28 changes: 28 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import js from '@eslint/js'
import eslintPluginVue from 'eslint-plugin-vue'
import ts from 'typescript-eslint'

export default ts.config(
js.configs.recommended,
...ts.configs.recommended,
...eslintPluginVue.configs['flat/recommended'],
{
files: ['*.vue', '**/*.vue'],
languageOptions: {
parserOptions: {
parser: '@typescript-eslint/parser'
}
},
rules: {
'vue/html-indent': ['warn', 4],
'vue/max-attributes-per-line': ['warn', {
singleline: {
max: 4
},
multiline: {
max: 1
}
}]
}
}
)
3 changes: 3 additions & 0 deletions module.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
declare module "virtual:gitrev" {
export const rev: string
}

declare module "eslint-plugin-vue"
declare module "@eslint/js"
574 changes: 173 additions & 401 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 5 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,35 @@
"preview": "vite preview",
"build-only": "vite build",
"type-check": "vue-tsc --noEmit",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"lint": "eslint 'src/**/*.{ts,js,vue}' --fix",
"format": "prettier --write src/",
"compose-up": "docker compose up --build"
},
"dependencies": {
"@typescript-eslint/parser": "^8.8.1",
"bootstrap-icons": "^1.11.3",
"eslint-plugin-vue": "^9.28.0",
"flag-icons": "^7.2.3",
"npm-run-all": "^4.1.5",
"parse-css-color": "^0.2.1",
"read-last-lines": "^1.8.0",
"typescript-eslint": "^8.8.1",
"vue": "^3.5.11",
"vue-eslint-parser": "^9.4.3",
"vue-i18n": "^10.0.4",
"vue-router": "^4.4.5"
},
"devDependencies": {
"@babel/types": "^7.25.7",
"@eslint/object-schema": "^2.1.4",
"@rushstack/eslint-patch": "^1.10.4",
"@tsconfig/node18": "^18.2.4",
"@types/node": "^22.7.5",
"@vitejs/plugin-vue": "^5.1.4",
"@vue/eslint-config-prettier": "^10.0.0",
"@vue/eslint-config-typescript": "^14.0.0",
"@vue/tsconfig": "^0.5.1",
"autoprefixer": "^10.4.20",
"eslint-plugin-vue": "^9.28.0",
"less": "^4.2.0",
"less-loader": "^12.2.0",
"prettier": "^3.3.3",
"typescript": "~5.6.3",
"typescript-eslint": "^8.8.1",
"vite": "^5.4.8",
"vite-plugin-vue-devtools": "^7.4.6",
"vue-tsc": "^2.1.6"
Expand Down
2 changes: 1 addition & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function getIsInert() {
</script>

<template>
<Header @menu-open-changed="(value : boolean) => (menuIsOpen = value)" />
<Header @menu-open-changed="(value: boolean) => (menuIsOpen = value)" />
<main :inert="getIsInert()">
<RouterView />
</main>
Expand Down
42 changes: 42 additions & 0 deletions src/backend/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// empty, as it is on the same domain
const productionUrl = ""
export type Route = `/${string}`
export type QueryParameters = { [key: string]: string }
export type Body = { [key: string]: unknown }

function getPath(route: Route = "/", query: QueryParameters) {
let url = import.meta.env.PROD
? productionUrl
: (import.meta.env.VITE_BACKEND_URL as string) || "https://jonathanbout.com"

if (url.endsWith("/")) {
url = url.slice(0, -1)
}

let queryString = "?"

for (const key in query) {
queryString += `${key}=${query[key]}&`
}

queryString = queryString.slice(0, -1)

return url + route + queryString
}


export default {
async get(route: Route, query: QueryParameters = {}) {
const fullUrl = new URL(getPath(route, query))

return await fetch(fullUrl)
},
async post(route: Route, body: Body, query: QueryParameters = {}) {
const fullUrl = new URL(getPath(route, query))

return await fetch(fullUrl, {
method: "POST",
body: JSON.stringify(body)
})
},
}
6 changes: 3 additions & 3 deletions src/components/BurgerMenuIconComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ defineProps<{
:style="'--animation-duration: ' + (animationDuration ?? '.3s')"
:class="'toggle-root' + (open ? ' open' : '')"
>
<div class="bar a"></div>
<div class="bar b"></div>
<div class="bar c"></div>
<div class="bar a" />
<div class="bar b" />
<div class="bar c" />
</div>
</template>
<style lang="less" scoped>
Expand Down
4 changes: 2 additions & 2 deletions src/components/FooterComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ const iconsByLocale: Localized<string> = {
<footer class="monospace" :inert="inert">
<div class="language-display" translate="no">
<ul>
<li v-for="locale in LOCALES" v-bind:key="locale">
<li v-for="locale in LOCALES" :key="locale">
<button
:class="'link no-external-icon' + (currentLocale === locale ? ' current' : '')"
@click="changeLanguage(locale)"
>
<i :class="'fi fi-' + iconsByLocale[locale]"></i>
<i :class="'fi fi-' + iconsByLocale[locale]" />
{{ $t("language." + locale) }}
</button>
</li>
Expand Down
5 changes: 3 additions & 2 deletions src/components/GitHubStatsComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,13 @@ function getTotalSizeFriendly(size: number) {
<template>
<div class="github-stats" translate="no">
<template v-if="stats.topLanguages.length > 0">
<div v-html="$t('projects.github-stats.top-languages.description')"></div>
<!-- eslint-disable-next-line vue/no-v-html -->
<div v-html="$t('projects.github-stats.top-languages.description')" />
<div class="percentage-bar" :style="getTotalSizeCSS()">
<div
:style="getCSS(stat)"
v-for="stat in stats.topLanguages"
:key="stat.name"
:style="getCSS(stat)"
:data-lang-name="stat.name"
:data-lang-percentage="getPercentageString(stat)"
:data-total-lang-size="getTotalSizeFriendly(stat.size)"
Expand Down
4 changes: 2 additions & 2 deletions src/components/LoaderComponent.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="spinner-root">
<template v-for="n in 10" v-bind:key="n">
<div :style="'--animation-delay: ' + (n - 1) * 0.06 + 's'" class="no-load-animation"></div>
<template v-for="n in 10" :key="n">
<div :style="'--animation-delay: ' + (n - 1) * 0.06 + 's'" class="no-load-animation" />
</template>
</div>
</template>
Expand Down
8 changes: 6 additions & 2 deletions src/components/PrivacyComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ function getParagraphs(paragraphs: string): string[] {
<h1>
{{ title }}
</h1>
<div class="state">{{ $t("privacy.lastUpdated") }}: {{ lastUpdate }}</div>
<p v-for="paragraph in transformedParagraphs" :key="paragraph">{{ paragraph }}</p>
<div class="state">
{{ $t("privacy.lastUpdated") }}: {{ lastUpdate }}
</div>
<p v-for="paragraph in transformedParagraphs" :key="paragraph">
{{ paragraph }}
</p>
</div>
</template>
28 changes: 15 additions & 13 deletions src/components/ProjectComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const projectName = computed(() => {
return props.project.name
}
return (props.project.name as any)[lang.value]
return (props.project.name as [])[lang.value]
})
</script>

Expand All @@ -44,19 +44,21 @@ const projectName = computed(() => {
class="image-wrapper"
:style="'--image-count: ' + (project.image ? 1 : project.images ? project.images.length : 0).toString()"
>
<img class="image" v-if="project.image" :src="project.image" alt="Project preview" />
<img v-if="project.image" class="image" :src="project.image" alt="Project preview">
<img
class="image"
v-else
v-for="image in project.images"
v-bind:key="image"
v-else
:key="image"
class="image"
:src="image"
alt="Project preview"
/>
>
</div>
<div class="vertical-stack">
<div class="name">{{ projectName }}</div>
<div class="description" v-if="project.description">
<div class="name">
{{ projectName }}
</div>
<div v-if="project.description" class="description">
{{ (project.description as any)[lang] }}
</div>
<ul class="links">
Expand All @@ -66,29 +68,29 @@ const projectName = computed(() => {
:aria-label="$t('projects.view-on-gh', { name: projectName })"
target="_blank"
class="bi bi-github big no-external-icon"
></a>
/>
</li>
<li v-if="project.demo">
<a
:href="project.demo"
:aria-label="$t('projects.view-demo', { name: projectName })"
target="_blank"
class="bi bi-box-arrow-up-right big no-external-icon"
></a>
/>
</li>
<li v-if="project.playStore">
<a
:href="project.playStore"
:aria-label="$t('projects.view-on-play-store', { name: projectName })"
target="_blank"
class="bi bi-google-play big no-external-icon"
></a>
/>
</li>
<li v-for="tag in project.tags" class="tag" v-bind:key="tag">
<li v-for="tag in project.tags" :key="tag" class="tag">
<TagComponent :tag="tag" />
</li>
</ul>
<div class="timeframe" v-if="project.timeframe">
<div v-if="project.timeframe" class="timeframe">
{{ timeframeText }}
</div>
</div>
Expand Down
8 changes: 3 additions & 5 deletions src/components/TagComponent.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
<script setup lang="ts">
import tagsData, { Tag } from "@/projects"
const props = defineProps({
tag: String
})
const props = defineProps<{tag:string}>()
const foundTag = (tagsData.tags as any)[props.tag || ""] as Tag
const foundTag = (tagsData.tags as [])[props.tag || ""] as Tag
let style: string | undefined = undefined
Expand Down Expand Up @@ -38,7 +36,7 @@ function getIconUrl() {
:src="getIconUrl()"
onerror="this.style.display = 'none';"
alt="icon"
/>
>
<span>
{{ foundTag?.name ?? tag }}
</span>
Expand Down
6 changes: 4 additions & 2 deletions src/components/forms/TextAreaInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@ updateCounter()
:required="required"
:minlength="minCharacters || undefined"
:maxlength="maxCharacters || undefined"
></textarea>
/>
<div :class="valid ? '' : 'invalid'">
{{ characterCount }}

<template v-if="minCharacters && characterCount < minCharacters"> / {{ minCharacters }} </template>
<template v-if="minCharacters && characterCount < minCharacters">
/ {{ minCharacters }}
</template>

<template v-if="maxCharacters && !(minCharacters && characterCount < minCharacters)">
/ {{ maxCharacters }}
Expand Down
2 changes: 1 addition & 1 deletion src/components/forms/TextInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const isValid = ref(true)
<template>
<label>
<span>{{ props.label }}</span>
<input :type="type" v-model="model" @input="validateInput" />
<input v-model="model" :type="type" @input="validateInput">
<span class="error" :class="validateInput() ? 'hidden' : 'visible'">{{ props.error }}</span>
</label>
</template>
22 changes: 12 additions & 10 deletions src/components/header/HeaderComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import BurgerMenuIconComponent from "../BurgerMenuIconComponent.vue"
import { useI18n } from "vue-i18n"
const emit = defineEmits<{
(e: "menuOpenChanged", value: boolean): void,
(e: "menuOpenChanged", value: boolean): void
}>()
let headerOpen = ref(false)
Expand Down Expand Up @@ -70,15 +70,17 @@ function transformPathName(index: number, part: string) {

<template>
<div class="menu-wrapper" :style="'--animation-duration: ' + animationDuration">
<div :class="'header-backdrop' + (headerOpen ? '' : ' closed')" @click="close_menu"></div>
<div :class="'header-backdrop' + (headerOpen ? '' : ' closed')" @click="close_menu" />
<button aria-label="menu" class="header-toggle" @click="toggle_menu">
<BurgerMenuIconComponent :animation-duration="animationDuration" :open="headerOpen" />
<div class="header-toggle-backdrop"></div>
<div class="header-toggle-backdrop" />
</button>
<div class="location-marker" v-if="fullPath() != '/'">
<router-link v-for="(part, index) in fullPathParts()" :to="{ path: basePath(index) }" v-bind:key="part">{{
transformPathName(index, part)
}}</router-link>
<div v-if="fullPath() != '/'" class="location-marker">
<router-link v-for="(part, index) in fullPathParts()" :key="part" :to="{ path: basePath(index) }">
{{
transformPathName(index, part)
}}
</router-link>
</div>
<header :class="'monospace' + (headerOpen ? '' : ' closed')">
<router-link to="/" active-class="active" class="site-title">
Expand All @@ -91,16 +93,16 @@ function transformPathName(index: number, part: string) {
<span>{{ $t("contact.title") }}</span>
</router-link>
<a href="https://github.com/JonathanBout" :aria-label="$t('header.github')" class="no-external-icon small">
<span><i class="bi bi-github"></i></span>
<span><i class="bi bi-github" /></span>
</a>
<a
href="https://linkedin.com/in/jonathanbout"
:aria-label="$t('header.linkedin')"
class="no-external-icon small"
>
<span><i class="bi bi-linkedin"></i></span>
<span><i class="bi bi-linkedin" /></span>
</a>
<div class="flex-filler"></div>
<div class="flex-filler" />
<div class="version">
<a :href="'https://github.com/JonathanBout/portfolio/commit/' + versionHash">{{
$t("version") + " " + versionHash
Expand Down
Loading

0 comments on commit fa634e9

Please sign in to comment.