├── src
├── assets
│ ├── logo.png
│ └── logo.svg
├── services
│ ├── api.js
│ ├── stats.js
│ ├── auth.js
│ ├── balance.js
│ ├── docs.js
│ ├── exmas.js
│ ├── questions.js
│ ├── playground.js
│ └── appointments.js
├── App.vue
├── styles
│ └── settings.scss
├── utils
│ └── fonthelper.js
├── main.js
├── plugins
│ ├── webfontloader.js
│ ├── index.js
│ ├── vuetify.js
│ └── auth.js
├── components
│ ├── Utils
│ │ ├── AppFooter.vue
│ │ ├── LoadingSpinner.vue
│ │ └── Login.vue
│ ├── Dashboard
│ │ ├── BalanceCard.vue
│ │ ├── ExamsCard.vue
│ │ ├── AppointmentCard.vue
│ │ └── StatsCard.vue
│ ├── Practice
│ │ ├── VideoPlayer.vue
│ │ └── PracticeQuestion.vue
│ └── Exams
│ │ ├── ExamResults.vue
│ │ ├── QuestionContainer.vue
│ │ └── ExamQuestion.vue
├── layouts
│ └── default
│ │ ├── View.vue
│ │ ├── AppBar.vue
│ │ └── Default.vue
├── views
│ ├── Playground
│ │ ├── IDQuestion.vue
│ │ ├── SearchResults.vue
│ │ ├── PlaygroundQuestion.vue
│ │ └── EntranceActivity.vue
│ ├── Practice.vue
│ ├── Exam.vue
│ ├── Documents.vue
│ ├── NotFound.vue
│ ├── Dashboard.vue
│ ├── BalanceHistory.vue
│ ├── AppointmentList.vue
│ └── About.vue
└── router
│ └── index.js
├── public
├── apple-icon-180.png
├── apple-splash-1136-640.jpg
├── apple-splash-1334-750.jpg
├── apple-splash-1792-828.jpg
├── apple-splash-640-1136.jpg
├── apple-splash-750-1334.jpg
├── apple-splash-828-1792.jpg
├── apple-splash-1125-2436.jpg
├── apple-splash-1170-2532.jpg
├── apple-splash-1179-2556.jpg
├── apple-splash-1242-2208.jpg
├── apple-splash-1242-2688.jpg
├── apple-splash-1284-2778.jpg
├── apple-splash-1290-2796.jpg
├── apple-splash-1536-2048.jpg
├── apple-splash-1620-2160.jpg
├── apple-splash-1668-2224.jpg
├── apple-splash-1668-2388.jpg
├── apple-splash-2048-1536.jpg
├── apple-splash-2048-2732.jpg
├── apple-splash-2160-1620.jpg
├── apple-splash-2208-1242.jpg
├── apple-splash-2224-1668.jpg
├── apple-splash-2388-1668.jpg
├── apple-splash-2436-1125.jpg
├── apple-splash-2532-1170.jpg
├── apple-splash-2556-1179.jpg
├── apple-splash-2688-1242.jpg
├── apple-splash-2732-2048.jpg
├── apple-splash-2778-1284.jpg
├── apple-splash-2796-1290.jpg
├── manifest-icon-192.maskable.png
├── manifest-icon-512.maskable.png
└── logo.svg
├── .gitignore
├── jsconfig.json
├── README.md
├── package.json
├── LICENSE
├── vite.config.js
└── index.html
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/src/assets/logo.png
--------------------------------------------------------------------------------
/public/apple-icon-180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-icon-180.png
--------------------------------------------------------------------------------
/public/apple-splash-1136-640.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-1136-640.jpg
--------------------------------------------------------------------------------
/public/apple-splash-1334-750.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-1334-750.jpg
--------------------------------------------------------------------------------
/public/apple-splash-1792-828.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-1792-828.jpg
--------------------------------------------------------------------------------
/public/apple-splash-640-1136.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-640-1136.jpg
--------------------------------------------------------------------------------
/public/apple-splash-750-1334.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-750-1334.jpg
--------------------------------------------------------------------------------
/public/apple-splash-828-1792.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-828-1792.jpg
--------------------------------------------------------------------------------
/public/apple-splash-1125-2436.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-1125-2436.jpg
--------------------------------------------------------------------------------
/public/apple-splash-1170-2532.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-1170-2532.jpg
--------------------------------------------------------------------------------
/public/apple-splash-1179-2556.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-1179-2556.jpg
--------------------------------------------------------------------------------
/public/apple-splash-1242-2208.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-1242-2208.jpg
--------------------------------------------------------------------------------
/public/apple-splash-1242-2688.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-1242-2688.jpg
--------------------------------------------------------------------------------
/public/apple-splash-1284-2778.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-1284-2778.jpg
--------------------------------------------------------------------------------
/public/apple-splash-1290-2796.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-1290-2796.jpg
--------------------------------------------------------------------------------
/public/apple-splash-1536-2048.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-1536-2048.jpg
--------------------------------------------------------------------------------
/public/apple-splash-1620-2160.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-1620-2160.jpg
--------------------------------------------------------------------------------
/public/apple-splash-1668-2224.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-1668-2224.jpg
--------------------------------------------------------------------------------
/public/apple-splash-1668-2388.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-1668-2388.jpg
--------------------------------------------------------------------------------
/public/apple-splash-2048-1536.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-2048-1536.jpg
--------------------------------------------------------------------------------
/public/apple-splash-2048-2732.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-2048-2732.jpg
--------------------------------------------------------------------------------
/public/apple-splash-2160-1620.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-2160-1620.jpg
--------------------------------------------------------------------------------
/public/apple-splash-2208-1242.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-2208-1242.jpg
--------------------------------------------------------------------------------
/public/apple-splash-2224-1668.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-2224-1668.jpg
--------------------------------------------------------------------------------
/public/apple-splash-2388-1668.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-2388-1668.jpg
--------------------------------------------------------------------------------
/public/apple-splash-2436-1125.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-2436-1125.jpg
--------------------------------------------------------------------------------
/public/apple-splash-2532-1170.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-2532-1170.jpg
--------------------------------------------------------------------------------
/public/apple-splash-2556-1179.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-2556-1179.jpg
--------------------------------------------------------------------------------
/public/apple-splash-2688-1242.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-2688-1242.jpg
--------------------------------------------------------------------------------
/public/apple-splash-2732-2048.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-2732-2048.jpg
--------------------------------------------------------------------------------
/public/apple-splash-2778-1284.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-2778-1284.jpg
--------------------------------------------------------------------------------
/public/apple-splash-2796-1290.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/apple-splash-2796-1290.jpg
--------------------------------------------------------------------------------
/public/manifest-icon-192.maskable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/manifest-icon-192.maskable.png
--------------------------------------------------------------------------------
/public/manifest-icon-512.maskable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KaratekHD/openbuzz/main/public/manifest-icon-512.maskable.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 | /dev-dist
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "esnext",
5 | "baseUrl": "./",
6 | "moduleResolution": "node",
7 | "paths": {
8 | "@/*": [
9 | "src/*"
10 | ]
11 | },
12 | "lib": [
13 | "esnext",
14 | "dom",
15 | "dom.iterable",
16 | "scripthost"
17 | ]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/services/api.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | import axios from "axios";
9 |
10 | export default (url = import.meta.env.VITE_API_BASE_URL) => {
11 | return axios.create({
12 | baseURL: url
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
21 |
--------------------------------------------------------------------------------
/src/styles/settings.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | /**
9 | * src/styles/settings.scss
10 | *
11 | * Configures SASS variables and Vuetify overwrites
12 | */
13 |
14 | // https://next.vuetifyjs.com/features/sass-variables/`
15 | // @use 'vuetify' with (
16 | // $color-pack: false
17 | // );
18 |
--------------------------------------------------------------------------------
/src/utils/fonthelper.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | import {useDisplay} from "vuetify";
9 |
10 | export default {
11 | get_header_size() {
12 | const {mobile} = useDisplay()
13 | if (mobile._object.xs) {
14 | return "text-h4"
15 |
16 | } else {
17 | return "text-h2"
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/src/services/stats.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | import api from "@/services/api";
9 |
10 |
11 | export default {
12 | answers(auth) {
13 | const route = '/student-question-answers/stats&learningModeId=1&studentEducationId=' + auth.student.education
14 | const config = {
15 | headers: {Authorization: `Bearer ${auth.token}`}
16 |
17 | }
18 |
19 | return api().get(route, config)
20 | }
21 | }
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | /**
9 | * main.js
10 | *
11 | * Bootstraps Vuetify and other plugins then mounts the App`
12 | */
13 |
14 | // Components
15 | import App from './App.vue'
16 |
17 | // Composables
18 | import { createApp } from 'vue'
19 |
20 | // Plugins
21 | import { registerPlugins } from '@/plugins'
22 |
23 | const app = createApp(App)
24 |
25 | registerPlugins(app)
26 |
27 | app.mount('#app')
28 |
--------------------------------------------------------------------------------
/src/plugins/webfontloader.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | /**
9 | * plugins/webfontloader.js
10 | *
11 | * webfontloader documentation: https://github.com/typekit/webfontloader
12 | */
13 |
14 | export async function loadFonts () {
15 | const webFontLoader = await import(/* webpackChunkName: "webfontloader" */'webfontloader')
16 |
17 | webFontLoader.load({
18 | google: {
19 | families: ['Roboto:100,300,400,500,700,900&display=swap'],
20 | },
21 | })
22 | }
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # base
2 |
3 | ## Project setup
4 |
5 | ```
6 | # yarn
7 | yarn
8 |
9 | # npm
10 | npm install
11 |
12 | # pnpm
13 | pnpm install
14 | ```
15 |
16 | ### Compiles and hot-reloads for development
17 |
18 | ```
19 | # yarn
20 | yarn dev
21 |
22 | # npm
23 | npm run dev
24 |
25 | # pnpm
26 | pnpm dev
27 | ```
28 |
29 | ### Compiles and minifies for production
30 |
31 | ```
32 | # yarn
33 | yarn build
34 |
35 | # npm
36 | npm run build
37 |
38 | # pnpm
39 | pnpm build
40 | ```
41 |
42 | ### Lints and fixes files
43 |
44 | ```
45 | # yarn
46 | yarn lint
47 |
48 | # npm
49 | npm run lint
50 |
51 | # pnpm
52 | pnpm lint
53 | ```
54 |
55 | ### Customize configuration
56 |
57 | See [Configuration Reference](https://vitejs.dev/config/).
58 |
--------------------------------------------------------------------------------
/src/plugins/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | /**
9 | * plugins/index.js
10 | *
11 | * Automatically included in `./src/main.js`
12 | */
13 |
14 | // Plugins
15 | import {loadFonts} from './webfontloader'
16 | import vuetify from './vuetify'
17 | import router from '../router'
18 | import { plugin } from './auth'
19 | import cookies from 'vue-cookies';
20 |
21 | export function registerPlugins(app) {
22 | loadFonts()
23 | app
24 | .use(vuetify)
25 | .use(router)
26 | .use(plugin)
27 | .use(cookies)
28 | }
29 |
--------------------------------------------------------------------------------
/src/services/auth.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | import api from "@/services/api";
9 |
10 | export default {
11 | login(username, password) {
12 | const payload = {"username": username, "password": password, "authClient": "DRIVE_BUZZ_WEB"}
13 | return api().post('/generate-token', payload)
14 | },
15 | getEducation(token) {
16 | const config = {
17 | headers: {Authorization: `Bearer ${token}`}
18 | }
19 | const endpoint = "/student-educations/with-theory/student/current"
20 | return api().get(endpoint, config)
21 | }
22 | }
--------------------------------------------------------------------------------
/src/services/balance.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | import api from "@/services/api";
9 |
10 | export default {
11 | getPayments(token) {
12 | const endpoint = '/education-events/student/current'
13 | const config = {
14 | headers: {Authorization: `Bearer ${token}`}
15 | }
16 | return api().get(endpoint, config)
17 | },
18 | getSaldo(token, id) {
19 | const config = {
20 | headers: {Authorization: `Bearer ${token}`}
21 | }
22 | let endpoint = "/balance/student-education/" + id
23 | return api().get(endpoint, config)
24 | }
25 | }
--------------------------------------------------------------------------------
/src/components/Utils/AppFooter.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 | Made with ❤️️ by KaratekHD .
13 |
14 |
15 |
16 | drive.buzz ist eine eingetragene Marke der Fahrschulcockpit GmbH.
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
26 |
27 |
--------------------------------------------------------------------------------
/src/plugins/vuetify.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | /**
9 | * plugins/vuetify.js
10 | *
11 | * Framework documentation: https://vuetifyjs.com`
12 | */
13 |
14 | // Styles
15 | import '@mdi/font/css/materialdesignicons.css'
16 | import 'vuetify/styles'
17 |
18 | // Composables
19 | import { createVuetify } from 'vuetify'
20 |
21 | // https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
22 | export default createVuetify({
23 | theme: {
24 | themes: {
25 | light: {
26 | colors: {
27 | primary: '#1867C0',
28 | secondary: '#5CBBF6',
29 | },
30 | },
31 | },
32 | },
33 | })
34 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "openbuzz",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "vite",
7 | "build": "vite build",
8 | "preview": "vite preview",
9 | "lint": "eslint . --fix --ignore-path .gitignore"
10 | },
11 | "dependencies": {
12 | "@mdi/font": "7.0.96",
13 | "@videojs-player/vue": "^1.0.0",
14 | "axios": "^1.2.2",
15 | "core-js": "^3.8.3",
16 | "roboto-fontface": "*",
17 | "video.js": "^7.20.3",
18 | "vue": "^3.2.13",
19 | "vue-cookies": "^1.8.2",
20 | "vue-router": "^4.0.0",
21 | "vuetify": "^3.0.0",
22 | "webfontloader": "^1.0.0"
23 | },
24 | "devDependencies": {
25 | "@vitejs/plugin-vue": "^3.0.3",
26 | "eslint": "^8.22.0",
27 | "eslint-plugin-vue": "^9.3.0",
28 | "sass": "^1.55.0",
29 | "vite": "^3.1.9",
30 | "vite-plugin-pwa": "^0.14.1",
31 | "vite-plugin-vuetify": "^1.0.0-alpha.12"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/layouts/default/View.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
39 |
--------------------------------------------------------------------------------
/src/services/docs.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | import api from "@/services/api";
9 |
10 | export default {
11 | async getDocuments(token) {
12 | if(token === undefined) {
13 | return []
14 | } else {
15 | const endpoint = '/student-documents/student/current'
16 | const config = {
17 | headers: {Authorization: `Bearer ${token}`}
18 | }
19 | const response = await api().get(endpoint, config)
20 | return response.data
21 | }
22 | },
23 | async getUnread(token) {
24 | const docs = await this.getDocuments(token)
25 | let unread = 0
26 | for (let i in docs) {
27 | if(!docs[i].seenByStudent) {
28 | unread++
29 | }
30 | }
31 | return unread
32 | }
33 | }
--------------------------------------------------------------------------------
/src/layouts/default/AppBar.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | OpenBuzz
22 |
23 |
24 |
25 |
29 |
30 |
31 |
32 |
33 |
40 |
--------------------------------------------------------------------------------
/src/services/exmas.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | import api from "@/services/api";
9 | import {useAuth} from "@/plugins/auth";
10 |
11 | export default {
12 | getExam() {
13 | const auth = useAuth()
14 | const route = '/theory-pre-exams&studentEducationId=' + auth.student.education
15 | const config = {
16 | headers: {Authorization: `Bearer ${auth.token}`}
17 | }
18 | return api().post(route, undefined, config)
19 | },
20 |
21 | submitExam(auth, answers, id) {
22 | const config = {
23 | headers: {Authorization: `Bearer ${auth.token}`}
24 | }
25 | const route = '/theory-pre-exams/add-question-answers/'
26 | return api().post(route, {"theoryPreExamId": id, "questionAnswers": answers}, config)
27 | },
28 | getHistory(auth) {
29 | const route = "/theory-pre-exams/student/current"
30 | const config = {
31 | headers: {Authorization: `Bearer ${auth.token}`}
32 | }
33 | return api().get(route, config)
34 | }
35 | }
--------------------------------------------------------------------------------
/src/components/Utils/LoadingSpinner.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 | Bitte warten...
23 |
24 |
25 |
26 |
27 |
28 |
30 |
31 |
--------------------------------------------------------------------------------
/src/services/questions.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | import api from "@/services/api";
9 | import {useAuth} from "@/plugins/auth";
10 |
11 | export default {
12 | next() {
13 | const auth = useAuth()
14 | const route = '/theory-questions/next&studentEducationId=' + auth.student.education
15 | const config = {
16 | headers: {Authorization: `Bearer ${auth.token}`}
17 | }
18 | return api().get(route, config)
19 | },
20 | nextWithToken(auth) {
21 | const route = '/theory-questions/next&studentEducationId=' + auth.student.education
22 | const config = {
23 | headers: {Authorization: `Bearer ${auth.token}`}
24 | }
25 | return api().get(route, config)
26 | },
27 | sendResult(auth, question, correct) {
28 | const route = '/student-question-answers'
29 | let payload = {"correct": correct, "studentEducationId": auth.student.education, "theoryQuestionId": question.id}
30 | if(question.withPicture) {
31 | payload["numberOfTimesPictureWasEnlarged"] = 0
32 | }
33 | const config = {
34 | headers: {Authorization: `Bearer ${auth.token}`}
35 | }
36 | api().post(route, payload, config)
37 | }
38 | }
--------------------------------------------------------------------------------
/src/components/Dashboard/BalanceCard.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | Kontostand
11 |
12 |
13 | {{ balance }} €
14 |
15 |
16 |
17 |
18 | Kontostand
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2023, KaratekHD
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this
9 | list of conditions and the following disclaimer.
10 |
11 | 2. Redistributions in binary form must reproduce the above copyright notice,
12 | this list of conditions and the following disclaimer in the documentation
13 | and/or other materials provided with the distribution.
14 |
15 | 3. Neither the name of the copyright holder nor the names of its
16 | contributors may be used to endorse or promote products derived from
17 | this software without specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 |
--------------------------------------------------------------------------------
/src/views/Playground/IDQuestion.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Spielwiese
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
48 |
49 |
--------------------------------------------------------------------------------
/public/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
19 |
26 |
28 |
29 |
--------------------------------------------------------------------------------
/src/components/Practice/VideoPlayer.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
46 |
47 |
--------------------------------------------------------------------------------
/src/services/playground.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | import api from "@/services/api";
9 |
10 | export default {
11 | get_categories(token) {
12 | const endpoint = "/question-groups"
13 | const config = {
14 | headers: {Authorization: `Bearer ${token}`}
15 | }
16 | return api().get(endpoint, config)
17 | },
18 | get_questions_by_category(token, name) {
19 | const endpoint = "/question-groups/" + name + "/questions"
20 | const config = {
21 | headers: {Authorization: `Bearer ${token}`}
22 | }
23 | return api().get(endpoint, config)
24 | },
25 | search_questions(mode, query, token) {
26 | const endpoint = "/theory-questions/student/filter"
27 | const config = {
28 | headers: {Authorization: `Bearer ${token}`}
29 | }
30 | let payload = {limit: 20, offset: 0}
31 | if(mode === 1) {
32 | // Freetext
33 | payload["freeText"] = query
34 | payload["officialNumber"] = ""
35 | } else {
36 | // Amtl. Nr.
37 | payload["officialNumber"] = query
38 | payload["freeText"] = ""
39 | }
40 | return api().post(endpoint, payload, config)
41 | },
42 | get_question_by_id(id, student, token) {
43 | const endpoint = '/theory-questions/' + id + '&studentEducationId=' + student
44 | const config = {
45 | headers: {Authorization: `Bearer ${token}`}
46 | }
47 | return api().get(endpoint, config)
48 | }
49 | }
--------------------------------------------------------------------------------
/src/views/Practice.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | Übungsbogen
11 |
12 |
13 | Du hast keine offenen Fragen mehr.
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
25 |
26 |
33 |
35 |
36 |
--------------------------------------------------------------------------------
/src/plugins/auth.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | import {inject} from 'vue'
9 | import authHelper from '@/services/auth'
10 |
11 | const injectionKey = Symbol('auth')
12 |
13 | export const useAuth = () => inject(injectionKey)
14 | export const plugin = {
15 | install(app) {
16 | let auth = {
17 | token: null,
18 | authorized: false,
19 | student: {"firstName": "", "lastName": "", "email": "", "id": ""},
20 | raw: null,
21 | login: async function (username, password) {
22 | const res = await authHelper.login(username, password)
23 | const data = res.data
24 | this.token = data.token
25 | const educationResult = await authHelper.getEducation(this.token)
26 | const educationData = educationResult.data
27 | this.authorized = true
28 | this.student = {
29 | "firstName": data.student.firstName,
30 | "lastName": data.student.lastName,
31 | "email": data.student.learnAppEmail,
32 | "id": data.student.id,
33 | "education": educationData[0].id
34 | }
35 | this.raw = data
36 | },
37 | loginCookie: async function (cookie) {
38 | console.log("Login with cookie!")
39 | const res = await authHelper.getEducation(cookie.token)
40 | if (res.status === 200) {
41 | this.student = cookie.student
42 | this.token = cookie.token
43 | this.authorized = true
44 | this.raw = cookie.raw
45 | return true
46 | } else {
47 | console.log("Login with cookie failed!")
48 | return false
49 | }
50 |
51 | }
52 |
53 |
54 | }
55 |
56 | app.provide(injectionKey, auth)
57 | app.config.globalProperties.$auth = auth
58 | }
59 |
60 | }
--------------------------------------------------------------------------------
/src/views/Exam.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 | Vorprüfung
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | Prüfungsergebnisse
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/views/Playground/SearchResults.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 | Suchergebnisse
12 |
13 |
{{ data.total }} Suchergebnisse für {{ route.query.query }} :
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | {{ item.officialNumber }}
22 |
23 |
24 | {{ item.title }}
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
57 |
58 |
--------------------------------------------------------------------------------
/src/views/Playground/PlaygroundQuestion.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Spielwiese
14 |
15 | In dieser Kategorie stehen derzeit keine Fragen zur
16 | Verfügung.
17 |
18 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
60 |
61 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | // Plugins
2 | import vue from '@vitejs/plugin-vue'
3 | import vuetify, {transformAssetUrls} from 'vite-plugin-vuetify'
4 |
5 | // Utilities
6 | import {defineConfig} from 'vite'
7 | import {fileURLToPath, URL} from 'node:url'
8 | import {VitePWA} from "vite-plugin-pwa";
9 |
10 | // https://vitejs.dev/config/
11 | export default defineConfig({
12 | plugins: [
13 | vue({
14 | template: {transformAssetUrls}
15 | }),
16 | VitePWA({
17 | registerType: 'autoUpdate',
18 | devOptions: {
19 | enabled: true
20 | },
21 | includeAssets: ['assets/*.svg'],
22 | manifest: {
23 | name: "OpenBuzz",
24 | short_name: "OpenBuzz",
25 | description: "Alternatives Frontend für drive.buzz Artemis",
26 | theme_color: '#ffffff',
27 | icons: [
28 | {
29 | "src": "manifest-icon-192.maskable.png",
30 | "sizes": "192x192",
31 | "type": "image/png",
32 | "purpose": "any"
33 | },
34 | {
35 | "src": "manifest-icon-192.maskable.png",
36 | "sizes": "192x192",
37 | "type": "image/png",
38 | "purpose": "maskable"
39 | },
40 | {
41 | "src": "manifest-icon-512.maskable.png",
42 | "sizes": "512x512",
43 | "type": "image/png",
44 | "purpose": "any"
45 | },
46 | {
47 | "src": "manifest-icon-512.maskable.png",
48 | "sizes": "512x512",
49 | "type": "image/png",
50 | "purpose": "maskable"
51 | }
52 | ]
53 | }
54 | }),
55 | // https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/vite-plugin
56 | vuetify({
57 | autoImport: true,
58 | styles: {
59 | configFile: 'src/styles/settings.scss',
60 | },
61 | }),
62 | ],
63 | define: {'process.env': {}},
64 | resolve: {
65 | alias: {
66 | '@': fileURLToPath(new URL('./src', import.meta.url))
67 | },
68 | extensions: [
69 | '.js',
70 | '.json',
71 | '.jsx',
72 | '.mjs',
73 | '.ts',
74 | '.tsx',
75 | '.vue',
76 | ],
77 | },
78 | server: {
79 | port: 3000,
80 | },
81 | })
82 |
--------------------------------------------------------------------------------
/src/views/Documents.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
13 |
14 | Dokumente
15 |
16 |
17 |
18 |
20 |
21 |
22 |
23 |
24 | {{ item.name }}
25 |
26 | {{ Intl.DateTimeFormat('de-DE', {dateStyle: 'long'}).format(new Date(item.createdOn)) }}
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
60 |
61 |
--------------------------------------------------------------------------------
/src/components/Utils/Login.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 | Willkommen zurück!
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
25 |
31 |
32 |
41 |
46 | Anmelden
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
77 |
--------------------------------------------------------------------------------
/src/components/Dashboard/ExamsCard.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | Vorprüfungen
11 |
12 | {{ success }} / {{ total }}
13 |
14 |
15 | {{
16 | new Intl.DateTimeFormat('de-DE', {dateStyle: 'long'}).format(new Date(exam.date))
17 | }}
18 | Fehlerpunkte: {{ exam.points }}
19 |
20 |
21 |
22 |
23 |
24 |
25 | Vorprüfungen
26 |
27 |
28 |
29 |
30 |
73 |
74 |
--------------------------------------------------------------------------------
/src/services/appointments.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | import api from "@/services/api";
9 | import balanceHelper from "@/services/balance";
10 |
11 | function now () { const d = new Date(); d.setHours(0, 0, 0, 0); return d }
12 |
13 | export default {
14 | async getEvents(token) {
15 | const endpoint = "/appointments/student/current"
16 | const config = {
17 | headers: {Authorization: `Bearer ${token}`}
18 | }
19 | let temp = []
20 | const response_appointments = await api().get(endpoint, config)
21 | const data_appointments = response_appointments.data
22 | temp.push.apply(temp, data_appointments)
23 | const response_balance = await balanceHelper.getPayments(token)
24 | const data_balance = response_balance.data
25 | for (const i in data_balance) {
26 | if (data_balance[i].educationEventType === "THEORY_EXAM") {
27 | temp.push({
28 | appointmentType: "THEORY_EXAM",
29 | name: data_balance[i].description,
30 | date: data_balance[i].date,
31 | appointmentId: null,
32 | time: null,
33 | duration: null,
34 | instructorInitials: null,
35 | note: null,
36 | seen: null,
37 | signed: null,
38 | student: null,
39 | standardProductShortName: "TE",
40 | licenseClass: data_balance[i].licenseClass
41 | })
42 | }
43 | }
44 | temp.sort(function (a, b) {
45 | const date1 = new Date(a.date)
46 | const date2 = new Date(b.date)
47 | return date1 - date2
48 | })
49 | temp.reverse()
50 | let up = []
51 | let done = []
52 | var now = new Date();
53 | now.setHours(0);
54 | now.setMinutes(0);
55 | now.setSeconds(0);
56 | now.setMilliseconds(0);
57 | for(const i in temp) {
58 | if(now.getTime() > (new Date(temp[i].date))) {
59 | done.push(temp[i])
60 | } else {
61 | up.push(temp[i])
62 | }
63 |
64 | }
65 | return {all: temp, up: up, done: done}
66 | }
67 | }
--------------------------------------------------------------------------------
/src/components/Exams/ExamResults.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 | Prüfung bestanden!
13 |
14 |
15 | Prüfung nicht bestanden.
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | Frage {{ index + 1 }}: {{ question.officialNumber }}
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Zur Startseite
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/views/NotFound.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | Die Seite, die du angefragt hast, konnten wir auf unseren Servern nicht finden. Hast
15 | du dich vielleicht vertippt?
16 |
17 |
18 |
19 |
24 |
29 | Country roads, take me home...
33 |
34 | Zurück zur Startseite
35 |
36 |
37 |
38 |
39 | 404
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
50 |
51 |
--------------------------------------------------------------------------------
/src/components/Dashboard/AppointmentCard.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
{{ title }}
12 |
Dein nächster Termin
13 |
14 |
15 | {{ date }}
16 |
17 | Datum
18 |
19 |
20 |
21 |
22 | {{ time }}
23 |
24 | Uhrzeit
25 |
26 |
27 |
28 |
29 |
30 |
31 | {{ duration }} Minuten
32 |
33 | Dauer
34 |
35 |
36 |
37 |
38 |
47 |
48 |
49 |
50 | Dein nächster Termin
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/src/components/Dashboard/StatsCard.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | Lernstatus
11 |
12 |
13 | {{ Math.round(percentage) }} %
20 |
21 |
22 |
23 |
24 | {{
25 | total
26 | }}
27 |
28 | Gesamt
29 |
30 |
31 |
32 | {{
33 | statistics.remaining
34 | }}
35 |
36 | Noch offen
37 |
38 |
39 |
40 | {{
41 | statistics.readyForExam
42 | }}
43 |
44 | Prüfungsreif
45 |
46 |
47 |
48 | {{
49 | Math.round((statistics.incorrectlyAnswered / (statistics.incorrectlyAnswered + statistics.readyForExam)) * 100)
50 | }} %
51 |
52 | Fehlerquote
53 |
54 |
55 |
56 |
57 |
58 |
59 | Lernstatus
60 |
61 |
62 |
63 |
64 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/src/components/Exams/QuestionContainer.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Wirklich abgeben?
14 |
15 |
16 | {{ props.questions.length - answers.length }} Fragen sind noch unbeantwortet.
17 |
18 |
19 | Nach Abgabe können keine Antworten mehr bearbeitet werden.
20 | Anschließend erfährst du, ob du die Prüfung bestanden hast oder nicht.
21 |
22 |
23 |
24 | Abbrechen
25 | Abgeben
26 |
27 |
28 |
29 |
30 | Frage: {{ model + 1 }}
31 |
32 |
33 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
108 |
--------------------------------------------------------------------------------
/src/views/Dashboard.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 | Hallo {{ auth.student.firstName }}!
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
38 | OpenBuzz ist ein alternatives Frontend für drive.buzz Artemis. Um es
39 | benutzen zu können, musst du dich
40 | mit deinen drive.buzz Zugangsdaten anmelden. Dies ist ein inoffizielles Projekt und steht in keiner
41 | Verbindung zu Fahrschulcockpit GmbH.
42 |
43 |
44 |
45 |
46 |
47 |
54 |
59 | Anmelden
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
105 |
106 |
111 |
--------------------------------------------------------------------------------
/src/views/BalanceHistory.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 | Mein Konto
13 |
14 |
15 | Kontostand
16 |
17 |
18 | {{ balance }} €
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
30 |
31 |
32 |
33 | Datum: {{
34 | new Intl.DateTimeFormat('de-DE', {dateStyle: 'long'}).format(new Date(item.date))
35 | }}
36 |
37 |
38 |
39 | Betrag: {{
40 | item.amountToPay
41 | }} €
42 |
43 |
44 | Betrag: {{
45 | item.amountPaid
46 | }} €
47 |
48 |
49 | Ausbilder: {{
50 | item.instructor.firstName
51 | }} {{ item.instructor.lastName }}
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/src/views/AppointmentList.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 | Termine
13 |
14 |
15 |
16 |
17 |
18 |
Anstehend
19 |
20 |
21 |
22 |
23 |
24 |
25 | {{ item.name }}
26 | {{ item.duration }}
27 | Minuten
28 |
29 |
30 |
31 | {{
32 | Intl.DateTimeFormat('de-DE', {dateStyle: 'short'}).format(new Date(item.date))
33 | }}
34 |
35 | {{
36 | Intl.DateTimeFormat('de-DE', {dateStyle: 'long'}).format(new Date(item.date))
37 | }}
38 |
39 | {{
40 | item.time
41 | }}
42 |
43 |
44 |
45 |
46 |
47 |
48 |
Abgeschlossen
49 |
50 |
51 |
52 |
53 |
54 |
55 | {{ item.name }}
56 |
57 | {{ item.duration }}
58 | Minuten
59 |
60 |
61 |
62 | {{
63 | Intl.DateTimeFormat('de-DE', {dateStyle: 'short'}).format(new Date(item.date))
64 | }}
65 |
66 | {{
67 | Intl.DateTimeFormat('de-DE', {dateStyle: 'long'}).format(new Date(item.date))
68 | }}
69 |
70 | {{
71 | item.time
72 | }}
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/src/views/Playground/EntranceActivity.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 | Spielwiese
13 |
14 |
15 |
16 |
17 | Fragen suchen
18 |
19 |
20 |
24 |
25 |
27 |
29 |
30 |
31 |
32 |
33 |
34 | Suchen
35 |
36 |
37 |
38 |
39 |
40 | Fragen nach Format
41 |
42 |
43 | Neue Fragen ({{
44 | stats.NEW_QUESTIONS
45 | }})
46 |
47 |
48 |
49 |
50 | Videofragen ({{
51 | stats.WITH_VIDEO
52 | }})
53 |
54 |
55 |
56 |
57 | Verkehrszeichen ({{
58 | stats.TRAFFIC_SIGNS
59 | }})
60 |
61 |
62 |
63 |
64 | Vorfahrt/Vorrang ({{
65 | stats.RIGHT_OF_WAY
66 | }})
67 |
68 |
69 |
70 |
71 | Zahlenfragen ({{
72 | stats.FREE_TEXT
73 | }})
74 |
75 |
76 |
77 |
78 | Faustformeln ({{
79 | stats.WITH_FORMULA
80 | }})
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
126 |
127 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | OpenBuzz
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/src/layouts/default/Default.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
14 |
15 |
16 |
17 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | Home
92 |
93 |
94 |
95 | Übungsbogen
96 |
97 |
98 |
99 | Vorprüfung
100 |
101 |
102 |
103 |
104 |
105 | Serviceworker aktualisiert.
106 |
107 | Die App muss neu gestartet bzw. die Seite neu geladen werden, damit die Änderungen in Kraft treten.
108 | Bitte beachte, dass die Änderungen möglicherweise nicht sichtbar sind.
109 |
110 |
111 |
112 | OK
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
189 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 KaratekHD. All rights reserverd.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | * This project is not affiliated with drive.buzz or Fahrschulcockpit.
6 | */
7 |
8 | // Composables
9 | import {createRouter, createWebHistory} from 'vue-router'
10 |
11 | const routes = [
12 | {
13 | path: '/',
14 | component: () => import('@/layouts/default/Default.vue'),
15 | children: [
16 | {
17 | path: '',
18 | name: 'Home',
19 | // route level code-splitting
20 | // this generates a separate chunk (about.[hash].js) for this route
21 | // which is lazy-loaded when the route is visited.
22 | component: () => import(/* webpackChunkName: "home" */ '@/views/Dashboard.vue'),
23 | }
24 | ],
25 | },
26 | {
27 | path: '/practice',
28 | component: () => import('@/layouts/default/Default.vue'),
29 | children: [
30 | {
31 | path: '',
32 | name: 'Übungsbogen',
33 | // route level code-splitting
34 | // this generates a separate chunk (about.[hash].js) for this route
35 | // which is lazy-loaded when the route is visited.
36 | component: () => import(/* webpackChunkName: "home" */ '@/views/Practice.vue'),
37 | },
38 | ],
39 | },
40 | {
41 | path: '/playground',
42 | component: () => import('@/layouts/default/Default.vue'),
43 | children: [
44 | {
45 | path: '',
46 | name: 'Spielwiese',
47 | // route level code-splitting
48 | // this generates a separate chunk (about.[hash].js) for this route
49 | // which is lazy-loaded when the route is visited.
50 | component: () => import(/* webpackChunkName: "home" */ '@/views/Playground/EntranceActivity.vue'),
51 | },
52 | ],
53 | },
54 | {
55 | path: '/playground/category/:categoryName',
56 | component: () => import('@/layouts/default/Default.vue'),
57 | children: [
58 | {
59 | path: '',
60 | name: 'Frage nach Kategorie',
61 | // route level code-splitting
62 | // this generates a separate chunk (about.[hash].js) for this route
63 | // which is lazy-loaded when the route is visited.
64 | component: () => import(/* webpackChunkName: "home" */ '@/views/Playground/PlaygroundQuestion.vue'),
65 | },
66 | ],
67 | },
68 | {
69 | path: '/playground/question/:questionID',
70 | component: () => import('@/layouts/default/Default.vue'),
71 | children: [
72 | {
73 | path: '',
74 | name: 'Frage nach ID',
75 | // route level code-splitting
76 | // this generates a separate chunk (about.[hash].js) for this route
77 | // which is lazy-loaded when the route is visited.
78 | component: () => import(/* webpackChunkName: "home" */ '@/views/Playground/IDQuestion.vue'),
79 | },
80 | ],
81 | },
82 | {
83 | path: '/playground/search',
84 | component: () => import('@/layouts/default/Default.vue'),
85 | children: [
86 | {
87 | path: '',
88 | name: 'Suchergebnisse',
89 | // route level code-splitting
90 | // this generates a separate chunk (about.[hash].js) for this route
91 | // which is lazy-loaded when the route is visited.
92 | component: () => import(/* webpackChunkName: "home" */ '@/views/Playground/SearchResults.vue'),
93 | },
94 | ],
95 | },
96 | {
97 | path: '/exam',
98 | component: () => import('@/layouts/default/Default.vue'),
99 | children: [
100 | {
101 | path: '',
102 | name: 'Vorprüfungen',
103 | // route level code-splitting
104 | // this generates a separate chunk (about.[hash].js) for this route
105 | // which is lazy-loaded when the route is visited.
106 | component: () => import(/* webpackChunkName: "home" */ '@/views/Exam.vue'),
107 | },
108 | ],
109 | },
110 | {
111 | path: '/balance',
112 | component: () => import('@/layouts/default/Default.vue'),
113 | children: [
114 | {
115 | path: '',
116 | name: 'Kontostand',
117 | // route level code-splitting
118 | // this generates a separate chunk (about.[hash].js) for this route
119 | // which is lazy-loaded when the route is visited.
120 | component: () => import(/* webpackChunkName: "home" */ '@/views/BalanceHistory.vue'),
121 | },
122 | ],
123 | },
124 | {
125 | path: '/appointments',
126 | component: () => import('@/layouts/default/Default.vue'),
127 | children: [
128 | {
129 | path: '',
130 | name: 'Termine',
131 | // route level code-splitting
132 | // this generates a separate chunk (about.[hash].js) for this route
133 | // which is lazy-loaded when the route is visited.
134 | component: () => import(/* webpackChunkName: "home" */ '@/views/AppointmentList.vue'),
135 | },
136 | ],
137 | },
138 | {
139 | path: '/docs',
140 | component: () => import('@/layouts/default/Default.vue'),
141 | children: [
142 | {
143 | path: '',
144 | name: 'Dokumente',
145 | // route level code-splitting
146 | // this generates a separate chunk (about.[hash].js) for this route
147 | // which is lazy-loaded when the route is visited.
148 | component: () => import(/* webpackChunkName: "home" */ '@/views/Documents.vue'),
149 | },
150 | ],
151 | },
152 | {
153 | path: '/about',
154 | component: () => import('@/layouts/default/Default.vue'),
155 | children: [
156 | {
157 | path: '',
158 | name: 'Über OpenBuzz',
159 | // route level code-splitting
160 | // this generates a separate chunk (about.[hash].js) for this route
161 | // which is lazy-loaded when the route is visited.
162 | component: () => import(/* webpackChunkName: "home" */ '@/views/About.vue'),
163 | },
164 | ],
165 | },
166 | {
167 | path: '/:pathMatch(.*)*',
168 | component: () => import('@/layouts/default/Default.vue'),
169 | children: [
170 | {
171 | path: '',
172 | name: 'NotFound',
173 | // route level code-splitting
174 | // this generates a separate chunk (about.[hash].js) for this route
175 | // which is lazy-loaded when the route is visited.
176 | component: () => import(/* webpackChunkName: "home" */ '@/views/NotFound.vue'),
177 | },
178 | ],
179 | },
180 |
181 | ]
182 |
183 | const router = createRouter({
184 | history: createWebHistory(process.env.BASE_URL),
185 | routes,
186 | })
187 |
188 | export default router
189 |
--------------------------------------------------------------------------------
/src/components/Practice/PracticeQuestion.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
17 |
18 |
19 | Bitte sieh dir den Film an, um dich mit der Situation vertraut zu machen. Der
20 | Film kann noch {{ 5 - amount_video_played }} Mal angesehen werden.
21 |
22 |
23 |
24 | Zur Aufgabenstellung
25 |
26 |
27 |
28 |
29 |
30 | Weiter
31 |
32 |
33 |
34 | {{ props.question.paragraph.name }} - {{ props.question.officialNumber }} - Punkte
35 | :
36 | {{ props.question.points }}
37 |
38 | {{ props.question.title }}
39 | {{ props.question.additionalText }}
40 |
41 |
42 |
43 |
44 |
47 |
48 |
49 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
59 | Überprüfen
60 |
61 | Weiter
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | {{ props.question.paragraph.name }} - {{ props.question.officialNumber }} - Punkte
77 | :
78 | {{ props.question.points }}
79 |
80 | {{ props.question.title }}
81 |
82 | {{ props.question.questionPattern }}
83 |
84 |
86 |
87 |
88 | Richtige Antwort: {{ props.question.correctAnswer }}
89 |
90 |
91 |
92 |
93 |
94 |
95 | Überprüfen
96 |
97 | Weiter
98 |
99 |
100 |
101 |
102 | Der Aufgabentyp {{ props.question.questionType }} kann von OpenBuzz nicht angezeigt
103 | werden.
104 | Weiter
105 |
106 |
107 |
108 |
109 |
110 |
111 |
228 |
229 |
--------------------------------------------------------------------------------
/src/views/About.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 | Über OpenBuzz
13 |
14 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | Autor
26 | KaratekHD
27 |
28 |
29 | Quellcode
30 | GitHub
31 |
32 |
33 | Lizenz
34 | BSD 3-Clause License
35 |
36 |
37 | Verwendete Bibliotheken
38 | Mehr erfahren
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Lizenzinformationen
49 |
50 |
51 | Copyright (c) 2023, KaratekHD
52 | Redistribution and use in source and binary forms, with or without
53 | modification, are permitted provided that the following conditions are met:
54 | 1. Redistributions of source code must retain the above copyright notice, this
55 | list of conditions and the following disclaimer.
56 | 2. Redistributions in binary form must reproduce the above copyright notice,
57 | this list of conditions and the following disclaimer in the documentation
58 | and/or other materials provided with the distribution.
59 | 3. Neither the name of the copyright holder nor the names of its
60 | contributors may be used to endorse or promote products derived from
61 | this software without specific prior written permission.
62 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
63 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
64 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
65 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
66 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
67 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
68 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
69 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
70 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
71 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72 |
73 | OK
74 |
75 |
76 |
77 |
78 |
79 | Verwendete Bibliotheken
80 |
81 |
82 |
83 |
84 |
85 | {{ item.title }} ({{ item.license }})
86 | {{ item.description }}
87 |
88 |
89 |
90 |
91 | OK
92 |
93 |
94 |
95 |
96 |
97 |
222 |
223 |
--------------------------------------------------------------------------------
/src/components/Exams/ExamQuestion.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | Bitte sieh dir den Film an, um dich mit der Situation vertraut zu machen. Der Film kann noch {{ 5 - amount_video_played }} Mal angesehen werden.
19 |
20 |
21 | Zur Aufgabenstellung
22 |
23 |
24 |
25 | {{ props.question.paragraph.name }} - {{ props.question.officialNumber }} - Punkte
26 | :
27 | {{ props.question.points }}
28 |
29 | {{ props.question.title }}
30 | {{ props.question.additionalText }}
31 |
32 |
33 |
34 |
35 |
38 |
39 |
40 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | {{ props.question.paragraph.name }} - {{ props.question.officialNumber }} - Punkte
60 | :
61 | {{ props.question.points }}
62 |
63 | {{ props.question.title }}
64 |
65 | Aufgrund technischer Limitierungen
66 | kann nur die richtige Antwort angezeigt werden, welche nicht zwingend mit der eingegebenen Lösung
67 | übereinstimmt.
68 |
69 |
70 |
71 | {{ props.question.questionPattern }}
72 |
73 |
75 |
76 |
77 | Richtige Antwort: {{ props.question.correctAnswer }}
78 |
79 |
80 |
81 |
82 |
83 |
84 | Der Aufgabentyp {{ props.question.questionType }} kann von OpenBuzz nicht angezeigt
85 | werden.
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | Abgabe
94 | Zurück
95 | Weiter
96 |
97 |
98 |
99 |
100 |
101 |
102 |
257 |
258 |
--------------------------------------------------------------------------------