remove frontend and all related services, scripts and code (#8860)

This commit is contained in:
Ulf Gebhardt 2025-09-05 15:30:08 +01:00 committed by GitHub
parent c1a05bc73b
commit 9bc327e675
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
606 changed files with 1 additions and 34536 deletions

View File

@ -126,80 +126,3 @@ updates:
day: "saturday"
timezone: "Europe/Berlin"
time: "03:00"
# frontend
# - package-ecosystem: npm
# open-pull-requests-limit: 99
# directory: "/frontend"
# rebase-strategy: "disabled"
# schedule:
# interval: weekly
# day: "saturday"
# timezone: "Europe/Berlin"
# time: "03:00"
# groups:
# eslint:
# applies-to: version-updates
# patterns:
# - "eslint*"
# - "@eslint*"
# pinia:
# applies-to: version-updates
# patterns:
# - "pinia*"
# react:
# applies-to: version-updates
# patterns:
# - "react*"
# remark:
# applies-to: version-updates
# patterns:
# - "remark*"
# storybook:
# applies-to: version-updates
# patterns:
# - "storybook"
# - "@storybook*"
# stylelint:
# applies-to: version-updates
# patterns:
# - "stylelint*"
# typescript:
# applies-to: version-updates
# patterns:
# - "ts*"
# - "@types*"
# - "typescript"
# vite:
# applies-to: version-updates
# patterns:
# - "vite"
# - "vite-plugin*"
# - "@vitejs/plugin-vue"
# vitest:
# applies-to: version-updates
# patterns:
# - "vitest"
# - "@vitest*"
# vue:
# applies-to: version-updates
# patterns:
# - "*vue?(/)*"
# exclude-patterns:
# - "vuetify"
# - "*vuepress*"
# - "vue-tsc"
# vuepress:
# applies-to: version-updates
# patterns:
# - "vuepress"
# - "@vuepress*"
# - package-ecosystem: docker
# open-pull-requests-limit: 99
# directory: "/frontend"
# rebase-strategy: "disabled"
# schedule:
# interval: weekly
# day: "saturday"
# timezone: "Europe/Berlin"
# time: "03:00"

View File

@ -30,24 +30,4 @@ vuepress: &vuepress
documentation: &documentation
- *vuepress
- *markdown
# frontend
frontend-test-lint-code: &frontend-test-lint-code
- 'frontend/**/*'
frontend-test-unit-code: &frontend-test-unit-code
- 'frontend/**/*'
frontend-test-build-code: &frontend-test-build-code
- 'frontend/**/*'
frontend-test-build-docker: &frontend-test-build-docker
- 'frontend/**/*'
frontend-test-build-docs: &frontend-test-build-docs
- 'frontend/**/*.md'
- 'frontend/.vuepress/*'
frontend-test-build-storybook: &frontend-test-build-storybook
- 'frontend/**/*'
- *markdown

View File

@ -1,37 +0,0 @@
name: "frontend:test:build test code"
on: push
jobs:
# only (but most important) job from this workflow required for pull requests
# check results serve as run conditions for all other jobs here
files-changed:
name: Detect File Changes - frontend-test-build-code
runs-on: ubuntu-latest
outputs:
changes: ${{ steps.changes.outputs.frontend-test-build-code }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.1.7
- name: Check for frontend file changes
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: changes
with:
token: ${{ github.token }}
filters: .github/file-filters.yml
list-files: shell
build:
if: needs.files-changed.outputs.changes == 'true'
name: Build - Frontend
needs: files-changed
runs-on: ubuntu-latest
env:
WORKING_DIRECTORY: ./frontend
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.1.7
- name: Frontend | Build
run: npm install && npm run build
working-directory: ${{env.WORKING_DIRECTORY}}

View File

@ -1,52 +0,0 @@
name: "frontend:test:build test docker"
on: push
jobs:
# only (but most important) job from this workflow required for pull requests
# check results serve as run conditions for all other jobs here
files-changed:
name: Detect File Changes - frontend-test-build-docker
runs-on: ubuntu-latest
outputs:
changes: ${{ steps.changes.outputs.frontend-test-build-docker }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.1.7
- name: Check for frontend file changes
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: changes
with:
token: ${{ github.token }}
filters: .github/file-filters.yml
list-files: shell
build-production:
if: needs.files-changed.outputs.changes == 'true'
name: Build Docker Production - Frontend
needs: files-changed
runs-on: ubuntu-latest
env:
WORKING_DIRECTORY: ./frontend
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.1.7
- name: Frontend | Build Docker Production
run: docker compose -f docker-compose.yml build
working-directory: ${{env.WORKING_DIRECTORY}}
build-development:
if: needs.files-changed.outputs.changes == 'true'
name: Build Docker Development - Frontend
needs: files-changed
runs-on: ubuntu-latest
env:
WORKING_DIRECTORY: ./frontend
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.1.7
- name: Frontend | Build Docker Development
run: docker compose build
working-directory: ${{env.WORKING_DIRECTORY}}

View File

@ -1,37 +0,0 @@
name: "frontend:test:build test docs"
on: push
jobs:
# only (but most important) job from this workflow required for pull requests
# check results serve as run conditions for all other jobs here
files-changed:
name: Detect File Changes - frontend-test-build-docs
runs-on: ubuntu-latest
outputs:
changes: ${{ steps.changes.outputs.frontend-test-build-docs }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.1.7
- name: Check for frontend file changes
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: changes
with:
token: ${{ github.token }}
filters: .github/file-filters.yml
list-files: shell
build:
if: needs.files-changed.outputs.changes == 'true'
name: Build Docs - Frontend
needs: files-changed
runs-on: ubuntu-latest
env:
WORKING_DIRECTORY: ./frontend
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.1.7
- name: Frontend | Build Docs
run: npm install && npm run docs:build
working-directory: ${{env.WORKING_DIRECTORY}}

View File

@ -1,37 +0,0 @@
name: "frontend:test:build test storybook"
on: push
jobs:
# only (but most important) job from this workflow required for pull requests
# check results serve as run conditions for all other jobs here
files-changed:
name: Detect File Changes - frontend-test-build-storybook
runs-on: ubuntu-latest
outputs:
changes: ${{ steps.changes.outputs.frontend-test-build-storybook }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.1.7
- name: Check for frontend file changes
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: changes
with:
token: ${{ github.token }}
filters: .github/file-filters.yml
list-files: shell
storybook:
if: needs.files-changed.outputs.changes == 'true'
name: Build Storybook - Frontend
needs: files-changed
runs-on: ubuntu-latest
env:
WORKING_DIRECTORY: ./frontend
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.1.7
- name: Frontend | Build Storybook
run: npm install && npm run storybook:build
working-directory: ${{env.WORKING_DIRECTORY}}

View File

@ -1,37 +0,0 @@
name: "frontend:test:lint code with defined linters"
on: push
jobs:
# only (but most important) job from this workflow required for pull requests
# check results serve as run conditions for all other jobs here
files-changed:
name: Detect File Changes - frontend-test-lint-code
runs-on: ubuntu-latest
outputs:
changes: ${{ steps.changes.outputs.frontend-test-lint-code }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.1.7
- name: Check for frontend file changes
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: changes
with:
token: ${{ github.token }}
filters: .github/file-filters.yml
list-files: shell
lint:
if: needs.files-changed.outputs.changes == 'true'
name: Lint - Frontend
needs: files-changed
runs-on: ubuntu-latest
env:
WORKING_DIRECTORY: ./frontend
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.1.7
- name: Frontend | Lint
run: npm install && npm run test:lint
working-directory: ${{env.WORKING_DIRECTORY}}

View File

@ -1,37 +0,0 @@
name: "frontend:test:unit test code with defined suites"
on: push
jobs:
# only (but most important) job from this workflow required for pull requests
# check results serve as run conditions for all other jobs here
files-changed:
name: Detect File Changes - frontend-test-unit-code
runs-on: ubuntu-latest
outputs:
changes: ${{ steps.changes.outputs.frontend-test-unit-code }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.1.7
- name: Check for frontend file changes
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: changes
with:
token: ${{ github.token }}
filters: .github/file-filters.yml
list-files: shell
unit:
if: needs.files-changed.outputs.changes == 'true'
name: Unit - Frontend
needs: files-changed
runs-on: ubuntu-latest
env:
WORKING_DIRECTORY: ./frontend
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.1.7
- name: Frontend | Unit
run: npm install && npm run test:unit
working-directory: ${{env.WORKING_DIRECTORY}}

View File

@ -108,7 +108,6 @@ jobs:
- name: backend | copy env files
run: |
cp webapp/.env.template webapp/.env
cp frontend/.env.dist frontend/.env
cp backend/.env.template backend/.env
- name: backend | docker compose

View File

@ -90,7 +90,6 @@ jobs:
- name: Copy env files
run: |
cp webapp/.env.template webapp/.env
cp frontend/.env.dist frontend/.env
cp backend/.env.template backend/.env
- name: backend | docker compose

View File

@ -30,7 +30,6 @@ jobs:
scopes: |
backend
webapp
frontend
maintenance
database
docu

View File

@ -11,18 +11,6 @@ services:
volumes:
- ./webapp:/app
frontend:
image: ghcr.io/ocelot-social-community/ocelot-social/frontend:local-development
build:
target: development
environment:
- NODE_ENV=development
ports:
# port required for npm run dev
- 24678:24678
volumes:
- ./frontend:/app
backend:
image: ghcr.io/ocelot-social-community/ocelot-social/backend:local-development
ports:

View File

@ -26,24 +26,6 @@ services:
env_file:
- ./webapp/.env
frontend:
image: ghcr.io/ocelot-social-community/ocelot-social/frontend:${OCELOT_VERSION:-latest}
build:
context: ./frontend
target: production
depends_on:
- backend
ports:
- 3002:3002
environment:
# Envs used in Dockerfile
# - DOCKER_WORKDIR="/app"
# - PORT="3002"
- NODE_ENV="production"
# Application only envs
#- HOST=0.0.0.0 # This is nuxt specific, alternative value is HOST=webapp
#- GRAPHQL_URI=http://backend:4000
backend:
image: ghcr.io/ocelot-social-community/ocelot-social/backend:${OCELOT_VERSION:-latest}
build:

View File

@ -1,5 +0,0 @@
node_modules/
build/
coverage/
.vuepress/.temp/
.vuepress/.cache/

View File

@ -1,5 +0,0 @@
# META
PUBLIC_ENV__META__BASE_URL="http://localhost:3000"
PUBLIC_ENV__META__DEFAULT_AUTHOR="IT Team 4 Change"
PUBLIC_ENV__META__DEFAULT_DESCRIPTION="IT4C Frontend Boilerplate"
PUBLIC_ENV__META__DEFAULT_TITLE="IT4C"

View File

@ -1,5 +0,0 @@
node_modules/
build/
coverage/
.storybook/
.vuepress/

View File

@ -1,182 +0,0 @@
// eslint-disable-next-line import/no-commonjs
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: [
'standard',
'eslint:recommended',
'plugin:@eslint-community/eslint-comments/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:import/recommended',
'plugin:import/typescript',
'plugin:promise/recommended',
'plugin:security/recommended-legacy',
'plugin:vue/vue3-recommended',
'plugin:@intlify/vue-i18n/recommended',
'plugin:storybook/recommended',
],
parserOptions: {
ecmaVersion: 'latest',
parser: '@typescript-eslint/parser',
sourceType: 'module',
},
plugins: ['@typescript-eslint', 'import', 'promise', 'security', 'vue', 'storybook'],
settings: {
'import/resolver': {
typescript: true,
node: true,
},
'vue-i18n': {
localeDir: './src/locales/*.json',
},
},
rules: {
'no-console': 'error',
'no-debugger': 'error',
camelcase: 'error',
indent: ['error', 2],
'linebreak-style': ['error', 'unix'],
semi: ['error', 'never'],
// This makes sure our vike router does not throw errors
'vue/multi-word-component-names': [
'error',
{
ignores: ['+Page'],
},
],
// Optional eslint-comments rule
'@eslint-community/eslint-comments/no-unused-disable': 'error',
'@eslint-community/eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }],
// import
'import/export': 'error',
'import/no-deprecated': 'error',
'import/no-empty-named-blocks': 'error',
'import/no-extraneous-dependencies': 'error',
'import/no-mutable-exports': 'error',
'import/no-unused-modules': 'error',
'import/no-named-as-default': 'error',
'import/no-named-as-default-member': 'error',
'import/no-amd': 'error',
'import/no-commonjs': 'error',
'import/no-import-module-exports': 'error',
'import/no-nodejs-modules': 'off',
'import/unambiguous': 'off', // not compatible with scriptless vue files
'import/default': 'error',
'import/named': 'error',
'import/namespace': 'error',
'import/no-absolute-path': 'error',
'import/no-cycle': 'error',
'import/no-dynamic-require': 'error',
'import/no-internal-modules': 'off',
'import/no-relative-packages': 'error',
'import/no-relative-parent-imports': [
'error',
{ ignore: ['#[src,root,components,pages,assets,layouts,stores,plugins,context,types]/*'] },
],
'import/no-self-import': 'error',
'import/no-unresolved': 'error',
'import/no-useless-path-segments': 'error',
'import/no-webpack-loader-syntax': 'error',
'import/consistent-type-specifier-style': 'error',
'import/exports-last': 'off',
'import/extensions': [
'error',
'never',
{
json: 'always',
},
],
'import/first': 'error',
'import/group-exports': 'off',
'import/newline-after-import': 'error',
'import/no-anonymous-default-export': 'off', // todo - consider to enable again
'import/no-default-export': 'off', // incompatible with vite & vike
'import/no-duplicates': 'error',
'import/no-named-default': 'error',
'import/no-namespace': 'error',
'import/no-unassigned-import': 'error',
'import/order': [
'error',
{
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'],
'newlines-between': 'always',
alphabetize: {
order: 'asc', // sort in ascending order. Options: ["ignore", "asc", "desc"]
caseInsensitive: true, // ignore case. Options: [true, false]
},
distinctGroup: true,
},
],
'import/prefer-default-export': 'off',
// promise
'promise/catch-or-return': 'error',
'promise/no-return-wrap': 'error',
'promise/param-names': 'error',
'promise/always-return': 'error',
'promise/no-native': 'off',
'promise/no-nesting': 'warn',
'promise/no-promise-in-callback': 'warn',
'promise/no-callback-in-promise': 'warn',
'promise/avoid-new': 'warn',
'promise/no-new-statics': 'error',
'promise/no-return-in-finally': 'warn',
'promise/valid-params': 'warn',
'promise/prefer-await-to-callbacks': 'error',
'promise/no-multiple-resolved': 'error',
},
overrides: [
{
files: ['*.ts', '*.tsx'],
parser: '@typescript-eslint/parser',
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json', '**/tsconfig.json'],
ecmaVersion: 'latest',
parser: '@typescript-eslint/parser',
sourceType: 'module',
},
plugins: ['@typescript-eslint'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
'plugin:@typescript-eslint/strict',
],
rules: {
// allow explicitly defined dangling promises
'@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }],
'no-void': ['error', { allowAsStatement: true }],
},
},
{
files: ['!*.json'],
plugins: ['prettier'],
extends: ['plugin:prettier/recommended'],
rules: {
'prettier/prettier': 'error',
},
},
{
files: ['*.json'],
plugins: ['json'],
extends: ['plugin:json/recommended-with-comments'],
},
{
files: ['*.vue'],
plugins: ['vuetify'],
extends: ['plugin:vuetify/recommended'],
},
{
files: ['*.[test,spec].[tj]s'],
plugins: ['vitest'],
extends: ['plugin:vitest/all'],
},
{
files: ['*.yaml', '*.yml'],
parser: 'yaml-eslint-parser',
plugins: ['yml'],
extends: ['plugin:yml/prettier'],
},
],
}

View File

@ -1 +0,0 @@
*

View File

@ -1,13 +0,0 @@
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
<!--
Please take a look at the issue templates at https://github.com/[ORGA/USER]/[REPO]/issues/new/choose
before submitting a new issue. Following one of the issue templates will ensure maintainers can route your request efficiently.
Thanks!
-->
## 💬 Issue
<!-- Describe your Issue in detail. -->
<!-- Attach screenshots and drawings if needed. -->

View File

@ -1,10 +0,0 @@
---
name: 🐛 Bug
about: Create a report to help us improve
labels: bug
title: 🐛 [Bug]
---
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
## 🐛 Bug
<!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the bug is.-->

View File

@ -1,10 +0,0 @@
---
name: 💥 DevOp
about: Help us manage our deployed Software.
labels: devops
title: 💥 [DevOps]
---
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
## 💥 DevOps
<!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the problem is.-->

View File

@ -1,13 +0,0 @@
---
name: 🌟 Epic
about: Define a big development Step
labels: epic
title: 🌟 [EPIC]
---
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
<!-- THIS ISSUE-TYPE IS NOT FOR YOU! -->
<!-- Proceed only if you know what you are doing - have a chat with Project's Team first -->
## 🌟 EPIC
<!-- Describe your Epic in detail. Include screenshots and drawings -->

View File

@ -1,10 +0,0 @@
---
name: 🚀 Feature
about: Suggest an idea for this project
labels: feature
title: 🚀 [Feature]
---
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
## 🚀 Feature
<!-- Give a short summary of the Feature. Use Screenshots if you want. -->

View File

@ -1,13 +0,0 @@
---
name: 💬 Question
about: If you need help understanding our Software.
labels: question
title: 💬 [Question]
---
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
<!-- Question the project's team -->
<!-- If you need an answer right away, consider to take other means of communication with the project's team -->
## 💬 Question
<!-- Describe your Question in detail. Include screenshots and drawings if needed. -->

View File

@ -1,10 +0,0 @@
---
name: 🔧 Refactor
about: Help us improve our code by refactoring it.
labels: refactor
title: 🔧 [Refactor]
---
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
## 🔧 Refactor
<!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the problem is.-->

View File

@ -1,13 +0,0 @@
---
name: 🎂 Release
about: Define a Release
labels: release
title: 🎂 [RELEASE]
---
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
<!-- THIS ISSUE-TYPE IS NOT FOR YOU! -->
<!-- Proceed only if you know what you are doing - have a chat with Project's Team first -->
## 🎂 RELEASE
<!-- Describe your Release in detail. Include screenshots and drawings -->

View File

@ -1,15 +0,0 @@
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
## 🍰 Pullrequest
<!-- Describe the Pullrequest. Use Screenshots if possible. -->
### Issues
<!-- Which Issues does this fix, which are related?
- fixes #XXX
- relates #XXX
-->
- None
### Todo
<!-- In case some parts are still missing, list them here. -->
- [X] None

View File

@ -1,21 +0,0 @@
name: "frontend:deploy:docs to github"
on:
push:
branches:
- master
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@9a9194f87191a7e9055e3e9b95b8cfb13023bb08 # v4.1.7
- name: vuepress-deploy
uses: jenkey2011/vuepress-deploy@875651a25c97353b9dcfc78c0c59b7dc09b8dbda # v1.8.1
env:
ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
#TARGET_REPO: username/repo
#TARGET_BRANCH: master
BUILD_SCRIPT: npm install && npm run docs:build
BUILD_DIR: build/docs/
VUEPRESS_BASE: "boilerplate-frontend"

9
frontend/.gitignore vendored
View File

@ -1,9 +0,0 @@
node_modules/
build/
coverage/
!.storybook/
!.vuepress/
.vuepress/.temp/
.vuepress/.cache/
build-storybook.log
.env

View File

@ -1 +0,0 @@
v24.2.0

View File

@ -1,14 +0,0 @@
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": false,
"singleQuote": true,
"quoteProps": "as-needed",
"jsxSingleQuote": true,
"trailingComma": "all",
"bracketSpacing": true,
"bracketSameLine": false,
"arrowParens": "always",
"endOfLine": "auto"
}

View File

@ -1,16 +0,0 @@
{
"plugins": [
"remark-gfm",
"remark-preset-lint-consistent",
"remark-preset-lint-markdown-style-guide",
"remark-preset-lint-recommended",
[
"remark-lint-maximum-line-length",
false
],
[
"remark-lint-list-item-indent",
"one"
]
]
}

View File

@ -1,26 +0,0 @@
<!-- .storybook/StoryWrapper.vue -->
<template>
<v-app :theme="themeName">
<v-main>
<slot name="story"></slot>
</v-main>
</v-app>
</template>
<script>
export const DEFAULT_THEME = 'light'
export default {
props: {
themeName: {
default: DEFAULT_THEME,
type: String,
},
},
}
</script>
<style>
.v-application .v-application__wrap {
min-height: unset;
}
</style>

View File

@ -1,22 +0,0 @@
import type { StorybookConfig } from '@storybook/vue3-vite'
const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/vue3-vite',
options: {},
},
docs: {
autodocs: 'tag',
},
core: {
disableTelemetry: true, // 👈 Disables telemetry
},
}
export default config

View File

@ -1,54 +0,0 @@
import { setup } from '@storybook/vue3'
import { createPinia } from 'pinia'
import { setPageContext } from '#context/usePageContext'
import i18n from '#plugins/i18n'
import CreateVuetify from '#plugins/vuetify'
import { withVuetifyTheme } from './withVuetifyTheme.decorator'
import type { Preview } from '@storybook/vue3'
setup((app) => {
// Registers your app's plugins into Storybook
const pinia = createPinia()
app.use(pinia)
app.use(i18n)
app.use(CreateVuetify(i18n))
setPageContext(app, { urlPathname: '' })
})
export const decorators = [withVuetifyTheme]
export const globalTypes = {
theme: {
name: 'Theme',
description: 'Global theme for components',
defaultValue: 'light',
toolbar: {
icon: 'paintbrush',
// Array of plain string values or MenuItem shape
items: [
{ value: 'light', title: 'Light', left: '🌞' },
{ value: 'dark', title: 'Dark', left: '🌛' },
],
// Change title based on selected value
dynamicTitle: true,
},
},
}
const preview: Preview = {
parameters: {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
}
export default preview

View File

@ -1,20 +0,0 @@
import { h } from 'vue'
import StoryWrapper, { DEFAULT_THEME } from './StoryWrapper.vue'
export const withVuetifyTheme = (storyFn, context) => {
// Pull our global theme variable, fallback to DEFAULT_THEME
const themeName = context.globals.theme || DEFAULT_THEME
const story = storyFn()
return () => {
return h(
StoryWrapper,
{ themeName }, // Props for StoryWrapper
{
// Puts your story into StoryWrapper's "story" slot with your story args
story: () => h(story, { ...context.args }),
},
)
}
}

View File

@ -1,9 +0,0 @@
{
"extends": [
"stylelint-config-standard",
"stylelint-config-standard-scss",
"stylelint-config-recommended-vue",
"stylelint-config-recess-order",
"stylelint-config-css-modules"
]
}

View File

@ -1,13 +0,0 @@
import { defaultTheme } from '@vuepress/theme-default'
import { viteBundler } from '@vuepress/bundler-vite'
import { defineUserConfig } from 'vuepress'
export default defineUserConfig({
title: 'IT4C Frontend Boilerplate Documentation',
description: 'IT4C Frontend Boilerplate Documentation',
dest: 'build/docs',
base: process.env.VUEPRESS_BASE ? `/${process.env.VUEPRESS_BASE}/` : '/',
pagePatterns: ['**/*.md', '**/LICENSE', '!.vuepress', '!node_modules'],
bundler: viteBundler({}),
theme: defaultTheme({}),
})

View File

@ -1,122 +0,0 @@
FROM node:21-alpine3.17 AS base
# ENVs (available in production aswell, can be overwritten by commandline or env file)
## DOCKER_WORKDIR would be a classical ARG, but that is not multi layer persistent - shame
ENV DOCKER_WORKDIR="/app"
## We Cannot do `$(date -u +'%Y-%m-%dT%H:%M:%SZ')` here so we use unix timestamp=0
ENV BUILD_DATE="1970-01-01T00:00:00.00Z"
## We cannot do $(npm run version).${BUILD_NUMBER} here so we default to 0.0.0.0
ENV BUILD_VERSION="0.0.0.0"
## We cannot do `$(git rev-parse --short HEAD)` here so we default to 0000000
ENV BUILD_COMMIT="0000000"
## SET NODE_ENV
ENV NODE_ENV="production"
## App relevant Envs
ENV PORT="3002"
# Labels
LABEL org.label-schema.build-date="${BUILD_DATE}"
LABEL org.label-schema.name="it4c:frontend"
LABEL org.label-schema.description="IT4C Frontend Boilerplate"
LABEL org.label-schema.usage="https://github.com/IT4Change/boilerplate-frontend/blob/master/README.md"
LABEL org.label-schema.url="https://github.com/IT4Change/boilerplate-frontend"
LABEL org.label-schema.vcs-url="https://github.com/IT4Change/boilerplate-frontend/tree/master/"
LABEL org.label-schema.vcs-ref="${BUILD_COMMIT}"
LABEL org.label-schema.vendor="IT4C"
LABEL org.label-schema.version="${BUILD_VERSION}"
LABEL org.label-schema.schema-version="1.0"
LABEL maintainer="info@it4c.dev"
# Install Additional Software
## install: node-gyp dependencies
# RUN apk --no-cache add g++ make python3
# Settings
## Expose Container Port
EXPOSE ${PORT}
EXPOSE 24678
## Workdir
RUN mkdir -p ${DOCKER_WORKDIR}
WORKDIR ${DOCKER_WORKDIR}
##################################################################################
# DEVELOPMENT (Connected to the local environment, to reload on demand) ##########
##################################################################################
FROM base AS development
# We don't need to copy or build anything since we gonna bind to the
# local filesystem which will need a rebuild anyway
# Run command
# (for development we need to execute npm install since the
# node_modules are on another volume and need updating)
CMD /bin/sh -c "npm install && npm run dev"
##################################################################################
# STORYBOOK ######################################################################
##################################################################################
FROM base AS storybook
# We don't need to copy or build anything since we gonna bind to the
# local filesystem which will need a rebuild anyway
# Run command
# (for development we need to execute npm install since the
# node_modules are on another volume and need updating)
CMD /bin/sh -c "npm install && npm run storybook"
##################################################################################
# DOCUMENTATION ##################################################################
##################################################################################
FROM base AS documentation
# We don't need to copy or build anything since we gonna bind to the
# local filesystem which will need a rebuild anyway
# Run command
# (for development we need to execute npm install since the
# node_modules are on another volume and need updating)
CMD /bin/sh -c "npm install && npm run docs:dev"
##################################################################################
# BUILD (Does contain all files and is therefore bloated) ########################
##################################################################################
FROM base AS build
# Copy everything
COPY . .
# npm install
RUN npm install --include=dev --frozen-lockfile --non-interactive
# npm build
RUN npm run build
##################################################################################
# TEST ###########################################################################
##################################################################################
#FROM build AS test
# Install Additional Software
# RUN apk add --no-cache bash jq
# Run command
#CMD /bin/sh -c "yarn run dev"
##################################################################################
# PRODUCTION (Does contain only "binary"- and static-files to reduce image size) #
##################################################################################
FROM base AS production
# Copy "binary"-files from build image
COPY --from=build ${DOCKER_WORKDIR}/build ./build
# Copy server
COPY --from=build ${DOCKER_WORKDIR}/server ./server
# Copy package.json & tsconfig.json
COPY --from=build ${DOCKER_WORKDIR}/package.json ./package.json
COPY --from=build ${DOCKER_WORKDIR}/package-lock.json ./package-lock.json
COPY --from=build ${DOCKER_WORKDIR}/tsconfig.json ./tsconfig.json
# Install production packages
RUN npm install --omit=dev --frozen-lockfile --non-interactive
# Run command
CMD /bin/sh -c "npm run server:prod"

View File

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2023 Ulf Gebhardt
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,177 +0,0 @@
# boilerplate-frontend
[![nodejs][badge-nodejs-img]][badge-nodejs-href]
[![npm][badge-npm-img]][badge-npm-href]
[![docker][badge-docker-img]][badge-docker-href]
[![jq][badge-jq-img]][badge-jq-href]
[![vue][badge-vue-img]][badge-vue-href]
[![vike][badge-vike-img]][badge-vike-href]
[![vuetify][badge-vuetify-img]][badge-vuetify-href]
[![pinia][badge-pinia-img]][badge-pinia-href]
[![vue-i18n][badge-vue-i18n-img]][badge-vue-i18n-href]
[![eslint][badge-eslint-img]][badge-eslint-href]
[![remark-cli][badge-remark-cli-img]][badge-remark-cli-href]
[![stylelint][badge-stylelint-img]][badge-stylelint-href]
[![vitest][badge-vitest-img]][badge-vitest-href]
[![storybook][badge-storybook-img]][badge-storybook-href]
[![vuepress][badge-vuepress-img]][badge-vuepress-href]
The IT4C Boilerplate for frontends
![](src/assets/it4c-logo2-clean-bg_alpha-128x128.png)
## Requirements & Technology
To be able to build this project you need `nodejs`, `npm` and optional `docker` and `jq`.
The project uses `vite` as builder, `vike` to do the SSR. The design framework is `vuetify` which requires the frontend framework `vue3`. For localization `vue-i18n` is used; Session storage is handled with `pinia`.
Testing is done with `vitest` and code style is enforced with `eslint`, `remark-cli` and `stylelint`.
This projects utilizes `storybook` to develop, document & test frontend components and `vuepress` for static documentation generation.
## Commands
The following commands are available:
| Command | Description |
| --------------------------- | ------------------------------------------------ |
| `npm install` | Project setup |
| `npm run build` | Compiles and minifies for production |
| `npm run server:prod` | Runs productions server |
| **Develop** | |
| `npm run dev` | Compiles and hot-reloads for development |
| `npm run server:dev` | Run development server |
| `npm run server:prod:ts` | Run production server without build (ts-node) |
| `npm run server:build` | Build Server into an executable cjs file |
| **Test** | |
| `npm run test:lint` | Run all linters |
| `npm run test:lint:eslint` | Run linter eslint |
| `npm run test:lint:locales` | Run linter locales |
| `npm run test:lint:remark` | Run linter remark |
| `npm run test:lint:style` | Run linter stylelint |
| `npm run test:unit` | Run all unit tests and generate coverage report |
| `npm run test:unit:update` | Run unit tests, coverage and update snapshots |
| `npm run test:unit:dev` | Run all unit tests in watch mode |
| `npm test` | Run all tests & linters |
| **Storybook** | |
| `npm run storybook` | Run Storybook |
| `npm run storybook:build` | Build static storybook |
| `npm run storybook:test` | Run tests against all storybook stories |
| **Documentation** | |
| `npm run docs:dev` | Run Documentation in development mode |
| `npm run docs:build` | Build static documentation |
| **Maintenance** | |
| `npm run update` | Check for updates |
### Docker
Docker can be run in development mode utilizing `docker-compose.overwrite.yml`:
```bash
docker compose up
```
Docker can be run in production mode:
```bash
docker compose -f docker-compose.yml up
```
### Update
You can get a list of packes to update by running `npm run update`.
Appending `-u ` will also update the packages in the `package.json`. You have to run `npm install` again after.
```bash
npm run update -- -u
npm install
```
## Endpoints
The following endpoints are provided given the right command is executed or all three if `docker compose` is used:
| Endpoint | Description |
| ---------------------------------------------- | ------------- |
| [http://localhost:3000](http://localhost:3000) | Web |
| [http://localhost:6006](http://localhost:6006) | Storybook |
| [http://localhost:8080](http://localhost:8080) | Documentation |
## How to use as part of a project
If you want to use this as part of a larger project, e.g. in conjunction with a backend also utilizing a boilerplate you cannot use the template mechanic provided by github for this repository.
You can use the following commands to include the whole git history of the boilerplate and be able to update according to changes to this repo using another remote.
```bash
git remote add xxx_boilerplate_frontend git@github.com:IT4Change/boilerplate-frontend.git
git fetch xxx_boilerplate_frontend
git merge -s ours --no-commit --allow-unrelated-histories xxx_boilerplate_frontend/master
git read-tree --prefix=xxx/ -u xxx_boilerplate_frontend/master
git commit -m "Imported boilerplate_frontend as a subtree under xxx/."
```
To update the subtree you can use
```bash
git subtree pull -P xxx/ xxx_boilerplate_frontend master
git commit -m "Updated boilerplate_frontend in subtree under xxx/."
```
Where `xxx` refers to the folder and product part you want to use the boilerplate in. This assumes that you might need several copies of the frontend boilerplate for you product.
This mechanic was taken from this [source](https://stackoverflow.com/questions/1683531/how-to-import-existing-git-repository-into-another/8396318#8396318)
## Known Problems
- [ ] [Image flicker](https://github.com/vuetifyjs/vuetify/issues/18772)
- [ ] [Black Buttons](https://github.com/vuetifyjs/vuetify/issues/18773)
## License
[Apache 2.0](./LICENSE)
<!-- Badges -->
[badge-nodejs-img]: https://img.shields.io/badge/nodejs-%3E%3D20.5.0-blue
[badge-nodejs-href]: https://nodejs.org/
[badge-npm-img]: https://img.shields.io/badge/npm-latest-blue
[badge-npm-href]: https://www.npmjs.com/package/npm
[badge-docker-img]: https://img.shields.io/badge/docker-latest-blue
[badge-docker-href]: https://www.docker.com/
[badge-jq-img]: https://img.shields.io/badge/jq-latest-blue
[badge-jq-href]: https://jqlang.github.io/jq/
[badge-vue-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=dependencies.vue&label=vue&color=green
[badge-vue-href]: https://vuejs.org/
[badge-vike-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=dependencies.vike&label=vike&color=green
[badge-vike-href]: https://vike.dev/
[badge-vuetify-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=dependencies.vuetify&label=vuetify&color=green
[badge-vuetify-href]: https://vuetifyjs.com/
[badge-pinia-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=dependencies.pinia&label=pinia&color=green
[badge-pinia-href]: https://pinia.vuejs.org/
[badge-vue-i18n-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=dependencies%5B%27vue-i18n%27%5D&label=vue-i18n&color=green
[badge-vue-i18n-href]: https://vue-i18n.intlify.dev/
[badge-eslint-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies.eslint&label=eslint&color=yellow
[badge-eslint-href]: https://eslint.org/
[badge-remark-cli-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies%5B%27remark-cli%27%5D&label=remark-cli&color=yellow
[badge-remark-cli-href]: https://remark.js.org/
[badge-stylelint-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies.stylelint&label=stylelint&color=yellow
[badge-stylelint-href]: https://stylelint.io/
[badge-vitest-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies.vitest&label=vitest&color=yellow
[badge-vitest-href]: https://vitest.dev/
[badge-storybook-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies.storybook&label=storybook&color=orange
[badge-storybook-href]: https://storybook.js.org/
[badge-vuepress-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies.vuepress&label=vuepress&color=orange
[badge-vuepress-href]: https://vuepress.vuejs.org/

View File

@ -1,64 +0,0 @@
version: '3.4'
services:
# ######################################################
# FRONTEND #############################################
# ######################################################
frontend:
# name the image so that it cannot be found in a DockerHub repository, otherwise it will not be built locally from the 'dockerfile' but pulled from there
image: it4c/frontend:local-development
build:
target: development
environment:
- NODE_ENV="development"
# - DEBUG=true
volumes:
# This makes sure the docker container has its own node modules.
# Therefore it is possible to have a different node version on the host machine
- frontend_node_modules:/app/node_modules
# bind the local folder to the docker to allow live reload
- ./:/app
# ######################################################
# STORYBOOK ############################################
# ######################################################
storybook:
# name the image so that it cannot be found in a DockerHub repository, otherwise it will not be built locally from the 'dockerfile' but pulled from there
image: it4c/frontend:local-storybook
build:
target: storybook
environment:
- NODE_ENV="development"
# - DEBUG=true
ports:
- 6006:6006
volumes:
# This makes sure the docker container has its own node modules.
# Therefore it is possible to have a different node version on the host machine
- storybook_node_modules:/app/node_modules
# bind the local folder to the docker to allow live reload
- ./:/app
# ######################################################
# DOCUMENTATION ########################################
# ######################################################
documentation:
# name the image so that it cannot be found in a DockerHub repository, otherwise it will not be built locally from the 'dockerfile' but pulled from there
image: it4c/frontend:local-documentation
build:
target: documentation
environment:
- NODE_ENV="development"
# - DEBUG=true
ports:
- 8080:8080
volumes:
# This makes sure the docker container has its own node modules.
# Therefore it is possible to have a different node version on the host machine
- documentation_node_modules:/app/node_modules
# bind the local folder to the docker to allow live reload
- ./:/app
volumes:
frontend_node_modules:
storybook_node_modules:
documentation_node_modules:

View File

@ -1,33 +0,0 @@
# This file defines the production settings. It is overwritten by docker-compose.override.yml,
# which defines the development settings. The override.yml is loaded by default. Therefore it
# is required to explicitly define if you want an production build:
# > docker-compose -f docker-compose.yml up
version: '3.4'
services:
frontend:
# name the image so that it cannot be found in a DockerHub repository, otherwise it will not be built locally from the 'dockerfile' but pulled from there
image: it4c/frontend:local-production
build:
context: .
target: production
networks:
- external-net
- internal-net
ports:
- 3000:3000
environment:
# Envs used in Dockerfile
# - DOCKER_WORKDIR="/app"
# - PORT=3000
# - BUILD_DATE="1970-01-01T00:00:00.00Z"
# - BUILD_VERSION="0.0.0.0"
# - BUILD_COMMIT="0000000"
- NODE_ENV="production"
# env_file:
# - ./.env
# - ./frontend/.env
networks:
external-net:
internal-net:
internal: true

23417
frontend/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,153 +0,0 @@
{
"name": "ocelot-social-frontend",
"version": "3.12.0",
"description": "ocelot.social new Frontend (in development and not fully implemented) by IT4C Boilerplate for frontends",
"main": "build/index.js",
"type": "module",
"repository": {
"type": "git",
"url": "git+https://github.com/IT4Change/boilerplate-frontend.git"
},
"keywords": [
"nodejs",
"npm",
"docker",
"jq",
"vue",
"vike",
"vuetify",
"pinia",
"vue-i18n",
"eslint",
"remark-cli",
"stylelint",
"vitest",
"storybook",
"vuepress"
],
"author": {
"name": "Ulf Gebhardt"
},
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/IT4Change/boilerplate-frontend/issues"
},
"homepage": "https://github.com/IT4Change/boilerplate-frontend#readme",
"scripts": {
"dev": "npm run server:dev",
"prod": "npm run build && npm run server:prod",
"build": "vite build && npm run server:build",
"server": "node --loader ts-node/esm ./server/index.ts",
"server:dev": "npm run server",
"server:prod": "node ./build/index.cjs",
"server:prod:ts": "cross-env NODE_ENV=production npm run server",
"server:build": "tsx scripts/buildServer/buildServer",
"storybook": "storybook dev -p 6006",
"storybook:build": "storybook build -o build/storybook",
"storybook:test": "test-storybook",
"test:lint": "npm run test:lint:eslint && npm run test:lint:remark && npm run test:lint:style && npm run test:lint:locales",
"test:lint:eslint": "eslint --ext .vue,.ts,.tsx,.js,.jsx,.cjs,.mjs,.json,.yml,.yaml --max-warnings 0 .",
"test:lint:locales": "scripts/locales/locales.sh src/locales",
"test:lint:remark": "remark . --quiet --frail",
"test:lint:style": "stylelint --max-warnings 0 --ignore-path .gitignore \"**/*.{css,scss,vue,vuex}\"",
"test:unit": "npm run test:unit:dev -- run --coverage",
"test:unit:update": "npm run test:unit:dev -- run --coverage -u",
"test:unit:dev": "vitest",
"test": "npm run test:lint && npm run test:unit",
"docs:dev": "vuepress dev .",
"docs:build": "vuepress build .",
"update": "npx npm-check-updates"
},
"dependencies": {
"@intlify/unplugin-vue-i18n": "^2.0.0",
"@mdi/font": "^7.4.47",
"@types/compression": "^1.7.5",
"@types/express": "^4.17.21",
"@types/node": "^20.13.0",
"@vitejs/plugin-vue": "^5.0.5",
"@vue/compiler-sfc": "^3.5.12",
"@vue/server-renderer": "3.4.27",
"@vuepress/theme-default": "^2.0.0-rc.37",
"compression": "^1.7.4",
"cross-env": "^7.0.3",
"express": "^4.21.1",
"pinia": "^2.2.4",
"pinia-plugin-persistedstate": "^4.1.2",
"sass": "^1.80.4",
"sass-loader": "^14.2.1",
"sirv": "^3.0.0",
"ts-node": "^10.9.2",
"typescript": "^5.4.5",
"vike": "^0.4.195",
"vite": "^5.2.12",
"vue": "3.4.27",
"vue-i18n": "^9.14.0",
"vuetify": "^3.5.15"
},
"devDependencies": {
"@eslint-community/eslint-plugin-eslint-comments": "^4.3.0",
"@intlify/eslint-plugin-vue-i18n": "^3.0.0",
"@storybook/addon-essentials": "^8.3.6",
"@storybook/addon-interactions": "^8.3.6",
"@storybook/addon-links": "^8.3.6",
"@storybook/blocks": "^8.1.10",
"@storybook/test-runner": "^0.19.1",
"@storybook/testing-library": "^0.2.2",
"@storybook/vue3": "^8.3.6",
"@storybook/vue3-vite": "^8.3.6",
"@typescript-eslint/eslint-plugin": "^7.11.0",
"@typescript-eslint/parser": "^7.11.0",
"@vitest/coverage-v8": "^2.1.3",
"@vue/test-utils": "^2.4.6",
"@vuepress/bundler-vite": "^2.0.0-rc.14",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-standard": "^17.1.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-json": "^3.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-security": "^3.0.0",
"eslint-plugin-storybook": "^0.8.0",
"eslint-plugin-vitest": "^0.4.1",
"eslint-plugin-vue": "^9.26.0",
"eslint-plugin-vuetify": "^2.4.0",
"eslint-plugin-yml": "^1.14.0",
"happy-dom": "^14.12.3",
"prettier": "^3.3.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"remark-cli": "^12.0.1",
"remark-gfm": "^4.0.0",
"remark-preset-lint-consistent": "^6.0.0",
"remark-preset-lint-markdown-style-guide": "^6.0.0",
"remark-preset-lint-recommended": "^7.0.0",
"storybook": "^8.1.10",
"stylelint": "^16.10.0",
"stylelint-config-css-modules": "^4.4.0",
"stylelint-config-recess-order": "^5.1.1",
"stylelint-config-recommended-vue": "^1.5.0",
"stylelint-config-standard": "^36.0.1",
"stylelint-config-standard-scss": "^13.1.0",
"tsx": "^4.11.0",
"vite-plugin-checker": "^0.6.4",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-vuetify": "^2.0.3",
"vitest": "^2.0.5",
"vue-tsc": "^1.8.27",
"vuepress": "^2.0.0-rc.14"
},
"imports": {
"#components/*": "./src/components/*",
"#pages/*": "./src/pages/*",
"#assets/*": "./src/assets/*",
"#layouts/*": "./src/layouts/*",
"#stores/*": "./src/stores/*",
"#src/*": "./src/*",
"#plugins/*": "./renderer/plugins/*",
"#context/*": "./renderer/context/*",
"#types/*": "./types/*",
"#root/*": "./*"
}
}

View File

@ -1,16 +0,0 @@
// See https://vike.dev/data-fetching
export default {
clientRouting: true,
prefetchStaticAssets: 'viewport',
passToClient: ['pageProps', /* 'urlPathname', */ 'routeParams'],
meta: {
title: {
// Make the value of `title` available on both the server- and client-side
env: { server: true, client: true },
},
description: {
// Make the value of `description` available only on the server-side
env: { server: true },
},
},
}

View File

@ -1,18 +0,0 @@
import { PageContext } from 'vike/types'
import { createApp } from './app'
import { getTitle } from './utils'
let instance: ReturnType<typeof createApp>
/* async */ function render(pageContext: PageContext) {
if (!instance) {
instance = createApp(pageContext)
instance.app.mount('#app')
} else {
instance.app.changePage(pageContext)
}
document.title = getTitle(pageContext)
}
export default render

View File

@ -1,74 +0,0 @@
import { renderToString as renderToString_ } from '@vue/server-renderer'
import { escapeInject, dangerouslySkipEscape } from 'vike/server'
import { PageContext, PageContextServer } from 'vike/types'
import logoUrl from '#assets/favicon.ico'
import image from '#assets/it4c-logo2-clean-bg_alpha-128x128.png'
import { META } from '#src/env'
import { createApp } from './app'
import { getDescription, getTitle } from './utils'
import type { App } from 'vue'
async function render(pageContext: PageContextServer & PageContext) {
const { app, i18n } = createApp(pageContext, false)
const locale = i18n.global.locale.value
const appHtml = await renderToString(app)
// See https://vike.dev/head
const title = getTitle(pageContext)
const description = getDescription(pageContext)
const documentHtml = escapeInject`<!DOCTYPE html>
<html lang="${locale}">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="${logoUrl}" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="${description}" />
<meta name="author" content="${META.DEFAULT_AUTHOR}">
<meta property="og:title" content="${title}" />
<meta property="og:type" content="website" />
<meta property="og:url" content="${META.BASE_URL}" />
<meta property="og:description" content="${description}" />
<meta property="og:image" content="${META.BASE_URL}${image}" />
<meta property="og:image:alt" content="${title}" />
<meta property="og:image:width" content="1200"/>
<meta property="og:image:height" content="601"/>
<meta name="twitter:card" content="summary_large_image" />
<!--<meta name="twitter:site" content="@YourTwitterUsername" />-->
<meta name="twitter:title" content="${title}" />
<meta name="twitter:text:title" content="${title}" />
<meta name="twitter:description" content="${description}" />
<meta name="twitter:image" content="${META.BASE_URL}${image}" />
<meta name="twitter:image:alt" content="${title}" />
<title>${title}</title>
</head>
<body>
<div id="app">${dangerouslySkipEscape(appHtml)}</div>
</body>
</html>`
return {
documentHtml,
pageContext: {
// We can add some `pageContext` here, which is useful if we want to do page redirection https://vike.dev/page-redirection
},
}
}
async function renderToString(app: App) {
let err: unknown
// Workaround: renderToString_() swallows errors in production, see https://github.com/vuejs/core/issues/7876
app.config.errorHandler = (err_) => {
err = err_
}
const appHtml = await renderToString_(app)
if (err) throw err
return appHtml
}
export default render

View File

@ -1,71 +0,0 @@
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import { PageContext } from 'vike/types'
import { createSSRApp, defineComponent, h, markRaw, reactive, Component } from 'vue'
import PageShell from '#components/PageShell.vue'
import { setPageContext } from '#context/usePageContext'
import i18n from '#plugins/i18n'
import pinia from '#plugins/pinia'
import CreateVuetify from '#plugins/vuetify'
const vuetify = CreateVuetify(i18n)
function createApp(pageContext: PageContext, isClient = true) {
// eslint-disable-next-line no-use-before-define
let rootComponent: InstanceType<typeof PageWithWrapper>
const PageWithWrapper = defineComponent({
data: () => ({
Page: markRaw(pageContext.Page),
pageProps: markRaw(pageContext.pageProps || {}),
isClient,
}),
created() {
// eslint-disable-next-line @typescript-eslint/no-this-alias
rootComponent = this
},
render() {
return h(
PageShell as Component,
{},
{
default: () => {
return h(this.Page, this.pageProps)
},
},
)
},
})
if (isClient) {
pinia.use(piniaPluginPersistedstate)
}
const app = createSSRApp(PageWithWrapper)
app.use(pinia)
app.use(i18n)
app.use(vuetify)
objectAssign(app, {
changePage: (pageContext: PageContext) => {
Object.assign(pageContextReactive, pageContext)
rootComponent.Page = markRaw(pageContext.Page)
rootComponent.pageProps = markRaw(pageContext.pageProps || {})
},
})
const pageContextReactive = reactive(pageContext)
setPageContext(app, pageContextReactive)
return { app, i18n }
}
// Same as `Object.assign()` but with type inference
function objectAssign<Obj extends object, ObjAddendum>(
obj: Obj,
objAddendum: ObjAddendum,
): asserts obj is Obj & ObjAddendum {
Object.assign(obj, objAddendum)
}
export { createApp }

View File

@ -1,22 +0,0 @@
// `usePageContext` allows us to access `pageContext` in any Vue component.
// See https://vike.dev/pageContext-anywhere
import { PageContext } from 'vike/types'
import { inject } from 'vue'
import type { App, InjectionKey } from 'vue'
export const vikePageContext: InjectionKey<PageContext> = Symbol('pageContext')
function usePageContext() {
const pageContext = inject(vikePageContext)
if (!pageContext) throw new Error('setPageContext() not called in parent')
return pageContext
}
function setPageContext(app: App, pageContext: PageContext) {
app.provide(vikePageContext, pageContext)
}
export { usePageContext }
export { setPageContext }

View File

@ -1,14 +0,0 @@
import { createI18n } from 'vue-i18n'
import de from '#src/locales/de.json'
// import { de as $vuetify } from 'vuetify/locale'
import en from '#src/locales/en.json'
// import { en as $vuetify } from 'vuetify/locale'
export default createI18n({
legacy: false, // Vuetify does not support the legacy mode of vue-i18n
globalInjection: true,
locale: 'de',
fallbackLocale: 'en',
messages: { de, en },
})

View File

@ -1,4 +0,0 @@
import { createPinia } from 'pinia'
const pinia = createPinia()
export default pinia

View File

@ -1,62 +0,0 @@
// eslint-disable-next-line import/no-unassigned-import
import 'vuetify/styles'
import { I18n, useI18n } from 'vue-i18n'
import { createVuetify, ThemeDefinition } from 'vuetify'
import { mdi } from 'vuetify/iconsets/mdi-svg'
import { createVueI18nAdapter } from 'vuetify/locale/adapters/vue-i18n'
import { aliases, set } from '#assets/icons'
import tokens from '#assets/sass/tokens.module.scss'
const lightTheme: ThemeDefinition = {
dark: false,
colors: {
background: tokens.backgroundColorBase,
surface: tokens.backgroundColorSoft,
primary: tokens.colorPrimary,
secondary: tokens.colorSecondary,
success: tokens.colorSuccess,
info: tokens.colorInfo,
warning: tokens.colorWarning,
error: tokens.colorError,
},
variables: {
'border-color': '#000000',
},
}
const darkTheme: ThemeDefinition = {
dark: true,
colors: {
...lightTheme.colors,
background: tokens.backgroundColorInverse,
surface: tokens.backgroundColorInverseSoft,
},
variables: {
'border-color': '#000000',
},
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default (i18n: I18n<any, NonNullable<unknown>, NonNullable<unknown>, string, false>) =>
createVuetify({
locale: {
adapter: createVueI18nAdapter({ i18n, useI18n }),
},
ssr: true,
icons: {
aliases,
defaultSet: 'ocelot',
sets: {
ocelot: set,
mdi,
},
},
theme: {
defaultTheme: 'light',
themes: {
light: lightTheme,
dark: darkTheme,
},
},
})

View File

@ -1,19 +0,0 @@
import { PageContext } from 'vike/types'
import { META } from '#src/env'
function getTitle(pageContext: PageContext) {
// The value exported by /pages/**/+title.js is available at pageContext.config.title
const val = pageContext.config.title
if (typeof val === 'string') return val
if (typeof val === 'function') return String(val(pageContext))
return META.DEFAULT_TITLE
}
function getDescription(pageContext: PageContext) {
const val = pageContext.config.description
if (typeof val === 'string') return val
if (typeof val === 'function') return val(pageContext)
return META.DEFAULT_DESCRIPTION
}
export { getTitle, getDescription }

View File

@ -1,56 +0,0 @@
import path from 'node:path'
import { fileURLToPath } from 'url'
// eslint-disable-next-line import/no-extraneous-dependencies
import { build } from 'esbuild'
// eslint-disable-next-line import/no-extraneous-dependencies
import fs, { ensureDir, remove } from 'fs-extra'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
async function buildServer() {
const result = await build({
absWorkingDir: process.cwd(),
entryPoints: [path.join(path.resolve(__dirname, '../../server/'), 'index.ts')],
outfile: 'index.cjs',
write: false,
minify: true,
platform: 'node',
bundle: true,
format: 'cjs',
sourcemap: false,
treeShaking: true,
define: { 'import.meta.url': 'importMetaUrl', 'process.env.NODE_ENV': '"production"' },
inject: [path.resolve(__dirname, './import.meta.url-polyfill.ts')],
banner: {
js: `/* eslint-disable prettier/prettier */`,
},
tsconfig: path.resolve(__dirname, './tsconfig.buildServer.json'),
plugins: [
{
name: 'externalize-deps',
setup(build) {
build.onResolve({ filter: /.*/ }, (args) => {
const id = args.path
if (id[0] !== '.' && !path.isAbsolute(id)) {
return {
external: true,
}
}
})
},
},
],
})
const { text } = result.outputFiles[0]
const filePath = path.join(path.resolve(__dirname, '../../build/'), 'index.cjs')
if (fs.existsSync(filePath)) {
await remove(filePath)
}
await ensureDir(path.dirname(filePath))
// eslint-disable-next-line import/no-named-as-default-member
await fs.writeFile(filePath, text)
}
void buildServer()

View File

@ -1,7 +0,0 @@
/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any */
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
export const importMetaUrl =
typeof document === 'undefined'
? (new (require('url').URL)('file:' + __filename) as URL).href
: (document.currentScript && (document.currentScript as any).src) ||
new URL('main.js', document.baseURI).href

View File

@ -1,16 +0,0 @@
{
"compilerOptions": {
"baseUrl": ".",
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"isolatedModules": true,
"lib": ["esnext", "dom", "DOM.Iterable"],
"strict": false,
"sourceMap": false,
"resolveJsonModule": true,
"skipLibCheck": true,
"esModuleInterop": true,
"declaration": false
}
}

View File

@ -1 +0,0 @@
path(..)|[.[]|tostring]|join(".")

View File

@ -1,44 +0,0 @@
#!/bin/bash
if [ $# -eq 0 ]
then
echo "You have to supply at least one argument specifying the folder to lint"
fi
FILES="$1"
tmp=$(mktemp)
exit_code=0
for locale_file in $FILES/*.json
do
jq -f $(dirname "$0")/sort.jq $locale_file > "$tmp"
# check sort order and fix it if required
if [ "$2" == "--fix" ]
then
mv "$tmp" $locale_file
else
if diff -q "$tmp" $locale_file > /dev/null ;
then
: # all good
else
exit_code=$?
echo "$(basename -- $locale_file) is not sorted by keys"
fi
fi
# check keys
if [ -n "$LAST_FILE" ]; then
listPaths="jq -f $(dirname "$0")/keys.jq"
diffString="<( cat $LAST_FILE | $listPaths ) <( cat $locale_file | $listPaths )"
if eval "diff -q $diffString";
then
: # all good
else
eval "diff -y $diffString | grep '[|<>]'";
printf "\n$LAST_FILE\" and $locale_file translation keys do not match, see diff above.\n"
exit_code=1
fi
fi
LAST_FILE=$locale_file
done
exit $exit_code

View File

@ -1,13 +0,0 @@
def walk(f):
. as $in
| if type == "object" then
reduce keys_unsorted[] as $key
( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
elif type == "array" then map( walk(f) ) | f
else f
end;
def keys_sort_by(f):
to_entries | sort_by(.key|f ) | from_entries;
walk(if type == "object" then keys_sort_by(ascii_upcase) else . end)

View File

@ -1,6 +0,0 @@
import { config } from '@vue/test-utils'
config.global.mocks = {
...config.global.mocks,
$t: (tKey: string) => "$t('" + tKey + "')", // just return translation key
}

View File

@ -1,8 +0,0 @@
import { config } from '@vue/test-utils'
import { vikePageContext } from '#context/usePageContext'
config.global.provide = {
...config.global.provide,
[vikePageContext as symbol]: { urlPathname: '/some-url' },
}

View File

@ -1,14 +0,0 @@
import { config } from '@vue/test-utils'
import i18n from '#plugins/i18n'
import vuetify from '#plugins/vuetify'
config.global.plugins.push(i18n)
config.global.plugins.push(vuetify(i18n))
config.global.mocks = {
...config.global.mocks,
i18n$t: i18n.global.t,
i18n$d: i18n.global.d,
i18n$n: i18n.global.n,
}

View File

@ -1,5 +0,0 @@
import { config } from '@vue/test-utils'
import pinia from '#plugins/pinia'
config.global.plugins.push(pinia)

View File

@ -1,97 +0,0 @@
// This file isn't processed by Vite, see https://github.com/vikejs/vike/issues/562
// Consequently:
// - When changing this file, you needed to manually restart your server for your changes to take effect.
// - To use your environment variables defined in your .env files, you need to install dotenv, see https://vike.dev/env
// - To use your path aliases defined in your vite.config.js, you need to tell Node.js about them, see https://vike.dev/path-aliases
// If you want Vite to process your server code then use one of these:
// - vavite (https://github.com/cyco130/vavite)
// - See vavite + Vike examples at https://github.com/cyco130/vavite/tree/main/examples
// - vite-node (https://github.com/antfu/vite-node)
// - HatTip (https://github.com/hattipjs/hattip)
// - You can use Bati (https://batijs.github.io/) to scaffold a Vike + HatTip app. Note that Bati generates apps that use the V1 design (https://vike.dev/migration/v1-design) and Vike packages (https://vike.dev/vike-packages)
import compression from 'compression'
import express from 'express'
import { renderPage } from 'vike/server'
import { root } from './root.js'
const isProduction = process.env.NODE_ENV === 'production'
void startServer()
async function startServer() {
const app = express()
// Vite integration
if (isProduction) {
// In production, we need to serve our static assets ourselves.
// (In dev, Vite's middleware serves our static assets.)
const sirv = (await import('sirv')).default
// assets 1y caching
app.use(
'/assets',
sirv(`${root}/build/client/assets`, {
maxAge: 31536000, // 1Y
immutable: true,
gzip: true,
}),
)
// cache things for 10min
app.use(
sirv(`${root}/build/client`, {
maxAge: 600,
immutable: true,
gzip: true,
}),
)
} else {
// We instantiate Vite's development server and integrate its middleware to our server.
// ⚠️ We instantiate it only in development. (It isn't needed in production and it
// would unnecessarily bloat our production server.)
const vite = await import('vite')
const viteDevMiddleware = (
await vite.createServer({
root,
server: { middlewareMode: true },
})
).middlewares
app.use(viteDevMiddleware)
// on the fly compression
app.use(compression())
}
// ...
// Other middlewares (e.g. some RPC middleware such as Telefunc)
// ...
// Vike middleware. It should always be our last middleware (because it's a
// catch-all middleware superseding any middleware placed after it).
app.get('*', (req, res, next) => {
void (async (req, res, next) => {
const pageContextInit = {
urlOriginal: req.originalUrl,
}
const pageContext = await renderPage(pageContextInit)
const { httpResponse } = pageContext
if (!httpResponse) {
next()
} else {
const { body, statusCode, headers, earlyHints } = httpResponse
if (res.writeEarlyHints)
res.writeEarlyHints({ link: earlyHints.map((e) => e.earlyHintLink) })
headers.forEach(([name, value]) => res.setHeader(name, value))
res.status(statusCode)
// For HTTP streams use httpResponse.pipe() instead, see https://vike.dev/stream
res.send(body)
}
})(req, res, next)
})
const port = process.env.PORT || 3000
app.listen(port)
// eslint-disable-next-line no-console
console.log(`🚀 Server running at http://localhost:${port}`)
}

View File

@ -1,8 +0,0 @@
// https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-when-using-the-experimental-modules-flag/50052194#50052194
import { dirname } from 'path'
import { fileURLToPath } from 'url'
const __dirname = dirname(fileURLToPath(import.meta.url))
const root = `${__dirname}/..`
export { root }

View File

@ -1,9 +0,0 @@
{
"extends": "../tsconfig.json",
// Make IDEs complain about missing file extension .js in import paths.
// Alternatively, we could always set "module" to "Node16" and add the file extension .js to import paths everywhere.
"compilerOptions": {
"module": "Node16",
"moduleResolution": "Node16"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,36 +0,0 @@
import { VIcon } from 'vuetify/components'
import { iconNames } from '#assets/icons'
import { SBComp } from '#types/SBComp'
import type { Meta, StoryObj } from '@storybook/vue3'
// More on how to set up stories at: https://storybook.js.org/docs/vue/writing-stories/introduction
const meta = {
title: 'Icons/Ocelot Icon Set',
component: VIcon as SBComp,
// This component will have an automatically generated docsPage entry: https://storybook.js.org/docs/vue/writing-docs/autodocs
tags: ['autodocs'],
argTypes: {
icon: { control: 'select', options: iconNames },
size: { control: 'select', options: ['x-small', 'small', 'default', 'large', 'x-large'] },
color: {
control: {
type: 'color',
presetColors: ['#000000', '#ff0000', '#00ff00', '#0000ff'],
},
},
},
args: { size: 'default', icon: '$heart', color: '' }, // default value
} satisfies Meta<typeof VIcon>
export default meta
type Story = StoryObj<typeof meta>
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/vue/api/csf
* to learn how to use render functions.
*/
export const Primary: Story = {
args: {},
}

View File

@ -1,28 +0,0 @@
import { mount } from '@vue/test-utils'
import { navigate } from 'vike/client/router'
import { describe, it, expect, beforeEach, vi } from 'vitest'
import { VIcon } from 'vuetify/components'
vi.mock('vike/client/router')
vi.mocked(navigate).mockResolvedValue()
describe('Ocelot Icons', () => {
const Wrapper = () => {
return mount(VIcon, {
props: {
icon: '$history',
color: 'green',
size: 'large',
},
})
}
let wrapper: ReturnType<typeof Wrapper>
beforeEach(() => {
wrapper = Wrapper()
})
it('renders and tests if the ocelot icon "$history" is installed', () => {
expect(wrapper.element).toMatchSnapshot()
})
})

View File

@ -1,28 +0,0 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`Ocelot Icons > renders and tests if the ocelot icon "$history" is installed 1`] = `
<i
aria-hidden="true"
class="v-icon notranslate v-theme--light v-icon--size-large text-green"
>
<!-- Generated by IcoMoon.io -->
<svg
fill="currentColor"
height="32"
stroke="currentColor"
version="1.1"
viewBox="0 0 32 32"
width="32"
xmlns="http://www.w3.org/2000/svg"
>
<title>
history
</title>
<path
d="M16 4c6.616 0 12 5.385 12 12s-5.385 12-12 12-12-5.385-12-12h2c0 5.535 4.465 10 10 10s10-4.465 10-10-4.465-10-10-10c-3.702 0-6.897 2.020-8.625 5h3.625v2h-7v-7h2v3.344c2.153-3.232 5.833-5.344 10-5.344zM15 8h2v7h5v2h-7v-9z"
/>
</svg>
</i>
`;

View File

@ -1,31 +0,0 @@
// usage:
// put source files in folder 'svgs'
// folder 'svgComponents' have to exist
// call script with command 'node convertSvgToVue.js'
// delete source files or whole folder
// run 'lint --fix' afterwards
import { readdirSync, readFileSync, writeFileSync } from 'fs'
import { join, parse } from 'path'
const inputDir = '../svgs'
const outputDir = '../svgComponents'
readdirSync(inputDir).forEach((file) => {
const filePath = join(inputDir, file)
const fileName = parse(file).name
// eslint-disable-next-line security/detect-non-literal-fs-filename
const content = readFileSync(filePath, 'utf8')
// add 'fill' and 'stroke' attributes to SVG code
const modifiedContent = content.replace(
/<svg([^>]*)>/,
'<svg$1 fill="currentColor" stroke="currentColor">',
)
const vueComponent = `<!-- eslint-disable vue/multi-word-component-names -->\n<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->\n<template>\n${modifiedContent}\n</template>\n`
const outputFilePath = join(outputDir, `${fileName}.vue`)
// eslint-disable-next-line security/detect-non-literal-fs-filename
writeFileSync(outputFilePath, vueComponent)
})

View File

@ -1,35 +0,0 @@
import { h } from 'vue'
import { IconProps } from 'vuetify'
import type { IconSet, IconAliases } from 'vuetify'
type Module = {
default: object
}
// see https://vitejs.dev/guide/features.html#glob-import
const iconModules: Record<string, Module> = import.meta.glob('./svgComponents/' + '*.vue', {
eager: true,
})
const icons: Record<string, Module> = {}
const iconNames: string[] = []
Object.entries(iconModules).forEach(([key, module]) => {
const iconName: string = key.split('/').slice(-1)[0].replace('.vue', '')
// eslint-disable-next-line security/detect-object-injection
icons[iconName] = module
iconNames.push('$' + iconName) // because it's used this way
})
const aliases: IconAliases = {} as IconAliases
Object.entries(icons).forEach(([key, value]) => {
Object.assign(aliases, { [key]: value.default })
})
const set: IconSet = {
component: (props: IconProps) =>
h(props.tag, [h(icons[props.icon as string], { class: 'v-icon__svg' })]),
}
export { iconNames, aliases, set }

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>align-center</title>
<path
d="M3 7h26v2h-26v-2zM7 11h18v2h-18v-2zM3 15h26v2h-26v-2zM7 19h18v2h-18v-2zM3 23h26v2h-26v-2z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>align-justify</title>
<path
d="M3 7h26v2h-26v-2zM3 11h26v2h-26v-2zM3 15h26v2h-26v-2zM3 19h26v2h-26v-2zM3 23h26v2h-26v-2z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>align-left</title>
<path
d="M3 7h26v2h-26v-2zM3 11h18v2h-18v-2zM3 15h26v2h-26v-2zM3 19h18v2h-18v-2zM3 23h26v2h-26v-2z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>align-right</title>
<path
d="M3 7h26v2h-26v-2zM11 11h18v2h-18v-2zM3 15h26v2h-26v-2zM11 19h18v2h-18v-2zM3 23h26v2h-26v-2z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>angellist</title>
<path
d="M12.813 4c0.312 0.021 0.615 0.118 0.875 0.25 0.521 0.265 0.919 0.67 1.281 1.125 0.725 0.91 1.311 2.103 1.813 3.313 0.207 0.498 0.39 0.985 0.563 1.469 0.109-0.401 0.21-0.808 0.344-1.219 0.391-1.201 0.902-2.395 1.594-3.344 0.346-0.474 0.731-0.895 1.25-1.188s1.174-0.421 1.813-0.281c0.628 0.138 1.091 0.677 1.281 1.156s0.24 0.97 0.25 1.5c0.020 1.060-0.168 2.29-0.406 3.5-0.385 1.96-0.863 3.535-1.063 4.188 0.328 0.248 0.624 0.516 0.844 0.813 1.025 1.382 0.75 3.010 0.75 3.375 0 4.219-1.55 6.731-3.406 8s-3.874 1.344-4.75 1.344c-0.805 0-2.922 0.024-4.938-0.906s-3.906-3.011-3.906-6.563c0-1.078 0.261-1.996 0.906-2.625 0.403-0.392 0.929-0.57 1.469-0.625-0.205-0.548-0.361-1.162-0.281-1.844 0.089-0.757 0.563-1.558 1.344-2.063 0.319-0.206 0.672-0.326 1.031-0.344 0.169-0.008 0.336 0.001 0.5 0.031-0.273-0.768-0.577-1.665-0.844-2.625-0.325-1.173-0.597-2.383-0.625-3.469-0.014-0.543 0.037-1.059 0.219-1.563s0.577-1.017 1.156-1.25c0.303-0.122 0.625-0.177 0.938-0.156zM12.656 5.969c-0.013-0.002-0.018 0.026-0.031 0.031 0.004 0.007-0.006 0.024-0.031 0.094-0.051 0.14-0.104 0.453-0.094 0.844 0.020 0.781 0.229 1.879 0.531 2.969 0.497 1.791 1.081 3.25 1.313 3.813 0.442-0.431 1.082-0.719 1.781-0.719h0.063c-0.255-0.9-0.658-2.135-1.25-3.563-0.465-1.121-1.026-2.178-1.531-2.813-0.253-0.317-0.492-0.526-0.625-0.594-0.066-0.034-0.103-0.060-0.125-0.063zM21.656 6.125c-0.047-0-0.102 0.001-0.156 0.031-0.168 0.095-0.391 0.304-0.625 0.625-0.468 0.641-0.925 1.687-1.281 2.781-0.488 1.498-0.754 2.761-0.906 3.594 0.721 0.094 1.355 0.232 1.906 0.406 0.238-0.82 0.595-2.103 0.906-3.688 0.224-1.139 0.39-2.277 0.375-3.063-0.006-0.332-0.054-0.548-0.094-0.688-0.040 0.001-0.078 0-0.125 0zM16.125 15c-0.248 0-0.319 0.061-0.406 0.156s-0.169 0.254-0.188 0.469c-0.015 0.179 0.007 0.355 0.063 0.5 0.046 0.070 0.080 0.147 0.125 0.219 0.020 0.024 0.040 0.042 0.063 0.063 0.062 0.056 0.14 0.102 0.219 0.125 1.258 0.369 2.844 0.844 2.844 0.844 0.399 0.115 0.723 0.546 0.723 0.961 0 0.444-0.352 0.881-0.785 0.977 0 0-0.565 0.117-1.125 0.469-0.348 0.218-0.665 0.461-0.844 0.813-0.109 0.214-0.156 0.468-0.156 0.781 0 0.866 0.241 1.414 0.469 1.75s0.375 0.406 0.375 0.406l-1.094 1.656s-0.515-0.316-0.938-0.938c-0.189-0.278-0.354-0.651-0.5-1.063-0.079 0.184-0.099 0.39-0.219 0.531-0.466 0.55-1.139 0.906-1.906 0.906-0.74 0-1.409-0.369-1.906-0.813s-0.89-0.987-1.281-1.594l1.688-1.094c0.346 0.537 0.672 0.982 0.938 1.219s0.412 0.281 0.563 0.281c0.124 0 0.312-0.113 0.375-0.188-0.216-0.366-0.428-0.696-0.656-1-0.988-1.312-2.049-2.044-2.656-2.188-0.376-0.089-0.483-0.046-0.594 0.063s-0.313 0.471-0.313 1.219c0 2.907 1.245 4.056 2.75 4.75s3.296 0.719 4.094 0.719c0.727 0 2.304-0.097 3.625-1s2.531-2.589 2.531-6.344c0-0.822 0.143-1.5-0.344-2.156s-1.846-1.5-5.531-1.5zM11.5 15.031c-0.34 0.22-0.376 0.367-0.406 0.625s0.025 0.662 0.188 1.063c0.324 0.802 0.938 1.531 0.938 1.531 0.663 0.506 1.276 1.177 1.875 2l0.063-0.031c-0.196-0.257-0.218-0.129-0.063-0.125s0.414-0.041 0.594-0.125 0.279-0.181 0.313-0.25 0.064-0.147-0.063-0.469c-0.536-1.37-1.376-2.666-2.156-3.438-0.39-0.386-0.765-0.63-1-0.719s-0.239-0.090-0.281-0.063z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>angle-down</title>
<path
d="M4.219 10.781l11.781 11.781 11.781-11.781 1.438 1.438-12.5 12.5-0.719 0.688-0.719-0.688-12.5-12.5z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>angle-left</title>
<path
d="M19.031 4.281l1.438 1.438-10.281 10.281 10.281 10.281-1.438 1.438-11-11-0.688-0.719 0.688-0.719z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>angle-right</title>
<path
d="M12.969 4.281l11 11 0.688 0.719-0.688 0.719-11 11-1.438-1.438 10.281-10.281-10.281-10.281z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>angle-up</title>
<path
d="M16 6.594l0.719 0.688 12.5 12.5-1.438 1.438-11.781-11.781-11.781 11.781-1.438-1.438 12.5-12.5z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>archive</title>
<path
d="M4 5h24v6h-1v16h-22v-16h-1v-6zM6 7v2h20v-2h-20zM7 11v14h18v-14h-18zM12.813 13c0.013-0.001 0.034-0.001 0.047-0.001s0.034 0.001 0.047 0.001c0.013-0.001 0.034-0.001 0.047-0.001s0.034 0.001 0.047 0.001l6.014-0c0.552 0 1 0.448 1 1s-0.448 1-1 1l-0.014-0h-6c-0.026 0.002-0.068 0.004-0.094 0.004-0.554 0-1.004-0.45-1.004-1.004 0-0.505 0.408-0.953 0.911-1z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>arrow-down</title>
<path
d="M15 4h2v20.063l6.781-6.781 1.438 1.438-8.5 8.5-0.719 0.688-0.719-0.688-8.5-8.5 1.438-1.438 6.781 6.781v-20.063z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>arrow-left</title>
<path
d="M13.281 6.781l1.438 1.438-6.781 6.781h20.063v2h-20.063l6.781 6.781-1.438 1.438-8.5-8.5-0.688-0.719 0.688-0.719z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>arrow-right</title>
<path
d="M18.719 6.781l8.5 8.5 0.688 0.719-0.688 0.719-8.5 8.5-1.438-1.438 6.781-6.781h-20.063v-2h20.063l-6.781-6.781z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>arrow-up</title>
<path
d="M16 4.094l0.719 0.688 8.5 8.5-1.438 1.438-6.781-6.781v20.063h-2v-20.063l-6.781 6.781-1.438-1.438 8.5-8.5z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>at</title>
<path
d="M16.188 4c6.337 0.093 11.62 5.29 11.813 11.625 0.005 0.143 0 0.274 0 0.406-0.012 3.289-2.716 5.97-6 5.969-1.271-0.001-2.391-0.628-3.125-1.563-0.827 0.948-2.027 1.563-3.375 1.563-2.473 0-4.5-2.027-4.5-4.5v-3c0-2.473 2.027-4.5 4.5-4.5 0.928 0 1.781 0.295 2.5 0.781v-0.781h2v8c0 1.116 0.883 1.999 2 2 2.208 0.001 3.992-1.766 4-3.969 0-0.122 0.003-0.231 0-0.344-0.16-5.253-4.589-9.61-9.844-9.688-6.165-0.090-11.048 5.348-10 11.719 0.696 4.234 4.182 7.613 8.438 8.188 2.919 0.394 5.61-0.452 7.656-2.094l1.25 1.563c-2.452 1.968-5.691 2.968-9.156 2.5-5.139-0.694-9.346-4.723-10.188-9.844-1.242-7.545 4.666-14.139 12.031-14.031zM15.5 12c-1.393 0-2.5 1.107-2.5 2.5v3c0 1.393 1.107 2.5 2.5 2.5s2.5-1.107 2.5-2.5v-3c0-1.393-1.107-2.5-2.5-2.5z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>balance-scale</title>
<path
d="M16 5c1.292 0 2.394 0.844 2.813 2h7.188v2h-1.406l0.281 0.5 4 7 0.125 0.25v0.25c0 2.75-2.25 5-5 5s-5-2.25-5-5v-0.25l0.125-0.25 4-7 0.281-0.5h-4.594c-0.304 0.84-0.973 1.509-1.813 1.813v13.188h4v2h-10v-2h4v-13.188c-0.842-0.304-1.507-0.969-1.813-1.813h-4.594l0.281 0.5 4 7 0.125 0.25v0.25c0 2.75-2.251 5-5 5s-5-2.25-5-5v-0.25l0.125-0.25 4-7 0.281-0.5h-1.406v-2h7.188c0.418-1.156 1.521-2 2.813-2zM16 7c-0.564 0-1 0.436-1 1s0.436 1 1 1 1-0.436 1-1-0.436-1-1-1zM8 12.031l-2.281 3.969h4.563zM24 12.031l-2.281 3.969h4.563zM5.25 18c0.402 1.161 1.444 2 2.75 2s2.348-0.839 2.75-2h-5.5zM21.25 18c0.402 1.161 1.444 2 2.75 2s2.348-0.839 2.75-2h-5.5z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>ban</title>
<path
d="M16 3c7.168 0 13 5.832 13 13s-5.832 13-13 13-13-5.832-13-13 5.832-13 13-13zM16 5c-2.647 0-5.073 0.918-6.969 2.469l15.344 15.656c1.635-1.919 2.625-4.399 2.625-7.125 0-6.087-4.913-11-11-11zM7.625 8.875c-1.635 1.919-2.625 4.399-2.625 7.125 0 6.087 4.913 11 11 11 2.647 0 5.073-0.918 6.969-2.469z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>bar-chart</title>
<path
d="M21 4h8v24h-8v-24zM23 6v20h4v-20h-4zM3 10h8v18h-8v-18zM5 12v14h4v-14h-4zM12 16h8v12h-8v-12zM14 18v8h4v-8h-4z"
></path>
</svg>
</template>

View File

@ -1,17 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>bars</title>
<path d="M4 7h24v2h-24v-2zM4 15h24v2h-24v-2zM4 23h24v2h-24v-2z"></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>bell</title>
<path
d="M15 3c1.105 0 2 0.895 2 2 0 0.085-0.021 0.168-0.031 0.25 3.521 0.924 6.031 4.273 6.031 8.031v8.719c0 0.565 0.435 1 1 1h1v2h-7.188c0.114 0.316 0.188 0.647 0.188 1 0 1.645-1.355 3-3 3s-3-1.355-3-3c0-0.353 0.073-0.684 0.188-1h-7.188v-2h1c0.565 0 1-0.435 1-1v-9c0-3.726 2.574-6.866 6.031-7.75-0.010-0.082-0.031-0.165-0.031-0.25 0-1.105 0.895-2 2-2zM14.563 7c-3.118 0.226-5.563 2.824-5.563 6v9c0 0.353-0.073 0.684-0.188 1h12.375c-0.114-0.316-0.188-0.647-0.188-1v-8.719c0-3.319-2.546-6.183-5.813-6.281-0.064-0.002-0.124-0-0.188 0-0.148 0-0.292-0.011-0.438 0zM15 25c-0.564 0-1 0.436-1 1s0.436 1 1 1 1-0.436 1-1-0.436-1-1-1z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>bold</title>
<path
d="M16 7h-9v18h11c2.8 0 5-2.2 5-5 0-2.2-1.4-4-3.3-4.7 0.8-0.9 1.3-2 1.3-3.3 0-2.8-2.2-5-5-5zM9 15v-6h7c1.7 0 3 1.3 3 3s-1.3 3-3 3h-7zM9 23v-6h9c1.7 0 3 1.3 3 3s-1.3 3-3 3h-9zM16 5v0c3.9 0 7 3.1 7 7 0 0.9-0.2 1.8-0.5 2.6 1.5 1.3 2.5 3.3 2.5 5.4 0 3.9-3.1 7-7 7h-13v-22h11zM11 11v0 2h5c0.6 0 1-0.4 1-1s-0.4-1-1-1h-5zM11 19v0 2h7c0.6 0 1-0.4 1-1s-0.4-1-1-1h-7z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>book</title>
<path
d="M10 5c2.92 0 5.482 0.981 6 1.188 0.518-0.206 3.080-1.188 6-1.188 3.227 0 6.375 1.313 6.375 1.313l0.625 0.281v20.406h-11.281c-0.346 0.597-0.979 1-1.719 1s-1.373-0.403-1.719-1h-11.281v-20.406l0.625-0.281s3.148-1.313 6.375-1.313zM10 7c-2.199 0-4.232 0.69-5 0.969v16.125c1.188-0.392 2.897-0.875 5-0.875 2.057 0 3.888 0.506 5 0.875v-16.125c-1-0.343-3.067-0.969-5-0.969zM22 7c-1.933 0-4 0.626-5 0.969v16.125c1.112-0.369 2.943-0.875 5-0.875 2.103 0 3.813 0.483 5 0.875v-16.125c-0.768-0.279-2.801-0.969-5-0.969z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>bookmark</title>
<path
d="M7 5h18v23l-1.594-1.188-7.406-5.563-7.406 5.563-1.594 1.188v-23zM9 7v17l6.406-4.813 0.594-0.438 0.594 0.438 6.406 4.813v-17h-14z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>briefcase</title>
<path
d="M16 3c1.864 0 3.399 1.275 3.844 3h9.156v20h-26v-20h9.156c0.445-1.725 1.98-3 3.844-3zM16 5c-0.81 0-1.428 0.385-1.75 1h3.5c-0.322-0.615-0.94-1-1.75-1zM5 8v9h22v-9h-22zM16 14c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM5 19v5h22v-5h-22z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>bug</title>
<path
d="M10.719 3.281l2.313 2.313c0.923-0.39 1.922-0.594 2.969-0.594s2.046 0.203 2.969 0.594l2.313-2.313 1.438 1.438-1.938 1.938c1.462 1.119 2.61 2.755 3.344 4.656l2.438-1.219 0.875 1.813-2.75 1.375c0.183 0.876 0.313 1.782 0.313 2.719 0 0.34-0.006 0.666-0.031 1h3.031v2h-3.375c-0.242 1.043-0.561 2.039-1.031 2.938l3 2.25-1.188 1.625-2.938-2.188c-1.618 2.056-3.885 3.375-6.469 3.375s-4.851-1.319-6.469-3.375l-2.938 2.188-1.188-1.625 3-2.25c-0.47-0.898-0.789-1.894-1.031-2.938h-3.375v-2h3.031c-0.025-0.334-0.031-0.66-0.031-1 0-0.937 0.13-1.843 0.313-2.719l-2.75-1.375 0.875-1.813 2.438 1.219c0.734-1.901 1.882-3.538 3.344-4.656l-1.938-1.938zM16 7c-1.978 0-3.827 1.094-5.125 2.875 1.134 0.511 2.924 1.125 5.125 1.125s3.991-0.614 5.125-1.125c-1.298-1.781-3.147-2.875-5.125-2.875zM9.906 11.594c-0.569 1.292-0.906 2.788-0.906 4.406 0 4.629 2.698 8.282 6 8.906v-11.969c-2.17-0.162-3.941-0.801-5.094-1.344zM22.094 11.594c-1.153 0.542-2.924 1.182-5.094 1.344v11.969c3.302-0.625 6-4.278 6-8.906 0-1.618-0.337-3.115-0.906-4.406z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>bullhorn</title>
<path
d="M28 3.031v9.156c1.156 0.418 2 1.521 2 2.813s-0.844 2.394-2 2.813v9.156l-1.594-1.156s-2.007-1.443-4.875-2.906-6.587-2.906-9.813-2.906h-3.375l1.625 5.719 0.344 1.281h-6.063l-0.219-0.719-2-7-0.031-0.156v-9.125h9.719c3.27 0 6.987-1.412 9.844-2.875s4.844-2.938 4.844-2.938zM26 6.75c-0.82 0.558-1.459 1.064-3.531 2.125-2.929 1.5-6.726 3.050-10.469 3.125v6c3.708 0.073 7.499 1.595 10.438 3.094 2.078 1.060 2.735 1.567 3.563 2.125v-16.469zM4 12v6h6v-6h-6zM4.344 20l1.406 5h1.906l-1.406-5h-1.906z"
></path>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
<!-- Generated by IcoMoon.io -->
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="currentColor"
stroke="currentColor"
>
<title>calculator</title>
<path
d="M5 3h20v26h-20v-26zM7 5v22h16v-22h-16zM9 7h12v6h-12v-6zM11 9v2h8v-2h-8zM10 15h2v2h-2v-2zM14 15h2v2h-2v-2zM18 15h2v2h-2v-2zM10 19h2v2h-2v-2zM14 19h2v2h-2v-2zM18 19h2v2h-2v-2zM10 23h2v2h-2v-2zM14 23h2v2h-2v-2zM18 23h2v2h-2v-2z"
></path>
</svg>
</template>

Some files were not shown because too many files have changed in this diff Show More