diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..fa3421e
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,127 @@
+
+
+
Lunchinator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/scss/style.scss b/src/assets/scss/style.scss
new file mode 100644
index 0000000..e6f3e91
--- /dev/null
+++ b/src/assets/scss/style.scss
@@ -0,0 +1,35 @@
+// required to get $orange variable
+$primary-dark: #737378;
+$primary: #d8ba9c;
+$secondary: #737378;
+
+@import "../../../node_modules/bootstrap/scss/functions";
+@import "../../../node_modules/bootstrap/scss/variables";
+@import "../../../node_modules/bootstrap/scss/variables-dark";
+@import "../../../node_modules/bootstrap/scss/maps";
+@import "../../../node_modules/bootstrap/scss/mixins";
+@import "../../../node_modules/bootstrap/scss/utilities";
+
+//$card-cap-bg: rgba(var(--#{$prefix}emphasis-color), 1);
+:root,
+[data-bs-theme="light"] {
+ --#{$prefix}custom-card-cap-bg: #{to-rgb($primary)};
+ --#{$prefix}soup-bg: #{$primary};
+}
+:root,
+[data-bs-theme="dark"] {
+ --#{$prefix}custom-card-cap-bg: #{to-rgb($primary-dark)};
+ --#{$prefix}soup-bg: #{$primary-dark};
+}
+
+$card-cap-bg: rgba(var(--#{$prefix}custom-card-cap-bg), .6);
+$pagination-active-bg: rgba(var(--#{$prefix}custom-card-cap-bg), 1);
+$pagination-active-border-color: rgba(var(--#{$prefix}custom-card-cap-bg), 1);
+$pagination-color: rgba(var(--#{$prefix}custom-card-cap-bg), 1);
+$pagination-hover-color: var(--#{prefix}card-cap-color);
+$form-check-input-checked-bg-color: rgba(var(--#{$prefix}custom-card-cap-bg), 1);
+$form-check-input-checked-border-color: rgba(var(--#{$prefix}custom-card-cap-bg), .5);
+$form-check-input-bg: rgba(var(--#{$prefix}custom-card-cap-bg), 1);
+
+// set changes
+@import "../../../node_modules/bootstrap/scss/bootstrap";
\ No newline at end of file
diff --git a/src/assets/vue.svg b/src/assets/vue.svg
new file mode 100644
index 0000000..770e9d3
--- /dev/null
+++ b/src/assets/vue.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/components/DaySelection.vue b/src/components/DaySelection.vue
new file mode 100644
index 0000000..6c8d7e9
--- /dev/null
+++ b/src/components/DaySelection.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/Menu.vue b/src/components/Menu.vue
new file mode 100644
index 0000000..0af7279
--- /dev/null
+++ b/src/components/Menu.vue
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ {{ menu.restaurant }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ soup.name }}
+
+
+
+ {{ soup.price < 0 ? '---' : soup.price }} Kč
+
+
+
+
+
+
+ {{ soup.name }}
+
+
+
+ {{ soup.price < 0 ? '---' : soup.price }} Kč
+
+
+
+
+
+
+ {{ meal.name }}
+
+
+
+ {{ meal.price < 0 ? '---' : meal.price }} Kč
+
+
+
+
+
+
+ {{ meal.name }}
+
+
+
+ {{ meal.price < 0 ? '---' : meal.price }} Kč
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/ThemeSelector.vue b/src/components/ThemeSelector.vue
new file mode 100644
index 0000000..d0f88aa
--- /dev/null
+++ b/src/components/ThemeSelector.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 0000000..47283e7
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,19 @@
+import { createApp } from 'vue'
+import './style.css'
+//import 'bootstrap/dist/css/bootstrap.css'
+//import 'font-awesome/css/font-awesome.min.css'
+import { library } from '@fortawesome/fontawesome-svg-core'
+import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
+import { faSun, faMoon, faArrowLeft, faArrowRight } from '@fortawesome/free-solid-svg-icons'
+import App from './App.vue'
+import { store, key } from './store';
+
+library.add(faSun);
+library.add(faMoon);
+library.add(faArrowLeft);
+library.add(faArrowRight);
+
+const app = createApp(App);
+app.component('font-awesome-icon', FontAwesomeIcon)
+app.use(store, key);
+app.mount('#app');
diff --git a/src/services/restaurantServices.ts b/src/services/restaurantServices.ts
new file mode 100644
index 0000000..7ee1a2d
--- /dev/null
+++ b/src/services/restaurantServices.ts
@@ -0,0 +1,23 @@
+import { Meal, Restaurant, RestaurantDay } from "../types/Restaurant"
+
+const noDataMeals: Meal[] = [
+ {
+ name: "No Data",
+ description: "The selected restaurant has no data for this day",
+ isSoup: false,
+ price: -1
+ }
+]
+
+export const restaurantToRestaurantDay = (data: Restaurant[]): RestaurantDay[] => {
+ const result = [];
+ for(const restaurant of data) {
+ result.push({
+ id: restaurant.id,
+ restaurant: restaurant.restaurant,
+ meals: restaurant.dailymenus[0].meals.length == 0 && restaurant.permanentmeals.length == 0 ? noDataMeals : restaurant.dailymenus[0].meals,
+ permanentmeals: restaurant.permanentmeals ?? [],
+ });
+ }
+ return result;
+}
\ No newline at end of file
diff --git a/src/store.ts b/src/store.ts
new file mode 100644
index 0000000..9741d95
--- /dev/null
+++ b/src/store.ts
@@ -0,0 +1,55 @@
+import { InjectionKey } from "vue";
+import { createStore, Store } from 'vuex';
+
+export interface State {
+ darkTheme: boolean
+ restaurantOrder: Map
+}
+
+export const key: InjectionKey> = Symbol();
+
+const restaurantOrderFromLocalStorage = (order: string | null): Map => {
+ const map = new Map();
+ if (!order) {
+ return map;
+ }
+ const entries = order.split(',');
+ for (let i = 0; i < entries.length; i += 2) {
+ const key = parseInt(entries[i]);
+ const value = parseInt(entries[i + 1]);
+ map.set(key, value);
+ }
+ return map;
+}
+
+const storeRestaurantOrder = (order: Map): void => {
+ let resultString = "";
+ for (const [key, value] of order.entries()) {
+ resultString += key.toString() + "," + value.toString() + ","
+ }
+ resultString = resultString.substring(0, resultString.length - 1);
+ window.localStorage.setItem("restaurantOrder", resultString);
+}
+
+export const store = createStore({
+ state: {
+ darkTheme: window.localStorage.getItem("darkTheme") === "true" ?? false,
+ restaurantOrder: restaurantOrderFromLocalStorage(window.localStorage.getItem("restaurantOrder"))
+ },
+ mutations: {
+ toggleDarkTheme(state: State) {
+ state.darkTheme = !state.darkTheme;
+ window.localStorage.setItem("darkTheme", state.darkTheme ? "true" : "false");
+ },
+ updateRestaurantOrder(state: State, payload: { id: number, newIndex: number, oldIndex: number, swapId: number }) {
+ const { id, newIndex, oldIndex, swapId } = payload;
+ state.restaurantOrder.set(swapId, oldIndex!);
+ state.restaurantOrder.set(id, newIndex);
+ storeRestaurantOrder(state.restaurantOrder);
+ },
+ setRestaurantOrder(state: State, payload: Map) {
+ state.restaurantOrder = payload
+ storeRestaurantOrder(state.restaurantOrder);
+ }
+ }
+})
\ No newline at end of file
diff --git a/src/style.css b/src/style.css
new file mode 100644
index 0000000..c2a3e91
--- /dev/null
+++ b/src/style.css
@@ -0,0 +1,3 @@
+#lunchinator {
+ font-family: 'Dancing Script', cursive;
+}
\ No newline at end of file
diff --git a/src/types/Restaurant.ts b/src/types/Restaurant.ts
new file mode 100644
index 0000000..a3d0a9c
--- /dev/null
+++ b/src/types/Restaurant.ts
@@ -0,0 +1,30 @@
+export type Restaurant = {
+ id: number
+ restaurant: string
+ dailymenus: Menu[]
+ permanentmeals: Meal[]
+}
+
+export type RestaurantDay = {
+ id: number,
+ restaurant: string
+ meals: Meal[]
+ permanentmeals: Meal[]
+}
+
+export type Menu = {
+ meals: Meal[]
+ day: string
+}
+
+export type Meal = {
+ name: string
+ description: string
+ isSoup: boolean
+ price: number
+}
+
+export enum Direction {
+ LEFT,
+ RIGHT
+}
\ No newline at end of file
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
new file mode 100644
index 0000000..74f3dca
--- /dev/null
+++ b/src/vite-env.d.ts
@@ -0,0 +1,8 @@
+///
+
+declare module "vuex" {
+ export * from "vuex/types/index.d.ts";
+ export * from "vuex/types/helpers.d.ts";
+ export * from "vuex/types/logger.d.ts";
+ export * from "vuex/types/vue.d.ts";
+}
\ No newline at end of file
diff --git a/src/vuex.d.ts b/src/vuex.d.ts
new file mode 100644
index 0000000..3619ba2
--- /dev/null
+++ b/src/vuex.d.ts
@@ -0,0 +1,13 @@
+import { Store } from 'vuex'
+
+declare module '@vue/runtime-core' {
+ // declare your own store states
+ interface State {
+ darkTheme: boolean
+ }
+
+ // provide typings for `this.$store`
+ interface ComponentCustomProperties {
+ $store: Store
+ }
+}
\ No newline at end of file