diff --git a/.idea/ferme.iml b/.idea/ferme.iml
index 63cff5a..0e3bfb4 100644
--- a/.idea/ferme.iml
+++ b/.idea/ferme.iml
@@ -137,6 +137,8 @@
+
+
diff --git a/.idea/php.xml b/.idea/php.xml
index 216185d..322587f 100644
--- a/.idea/php.xml
+++ b/.idea/php.xml
@@ -143,6 +143,8 @@
+
+
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 1af07c1..5e62f92 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -1,6 +1,291 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $PROJECT_DIR$/composer.json
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ "customColor": "",
+ "associatedIndex": 5
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1767956826164
+
+
+ 1767956826164
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ file://$PROJECT_DIR$/src/State/ReceptionWeighingProvider.php
+ 28
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/app.vue b/frontend/app.vue
index 4a62f0f..f8eacfa 100644
--- a/frontend/app.vue
+++ b/frontend/app.vue
@@ -1,3 +1,5 @@
-
+
+
+
diff --git a/frontend/composables/useApi.ts b/frontend/composables/useApi.ts
new file mode 100644
index 0000000..a9abd61
--- /dev/null
+++ b/frontend/composables/useApi.ts
@@ -0,0 +1,42 @@
+import type { FetchOptions } from 'ofetch'
+import { $fetch, FetchError } from 'ofetch'
+
+export type ApiClient = {
+ get(path: string, options?: FetchOptions<'json'>): Promise
+ post(path: string, body?: unknown, options?: FetchOptions<'json'>): Promise
+}
+
+export const useApi = (): ApiClient => {
+ const config = useRuntimeConfig()
+ const baseURL = config.public.apiBase ?? '/api'
+ const client = $fetch.create({ baseURL })
+
+ return {
+ get(path: string, options?: FetchOptions<'json'>) {
+ return client(path, { ...options, method: 'GET' })
+ },
+ post(path: string, body?: unknown, options?: FetchOptions<'json'>) {
+ return client(path, { ...options, method: 'POST', body })
+ }
+ }
+}
+
+export const getApiStatus = (error: unknown): number | null => {
+ if (error && typeof error === 'object') {
+ if (error instanceof FetchError) {
+ return error.status ?? error.response?.status ?? null
+ }
+
+ const maybeResponse = (error as { response?: { status?: number } }).response
+ if (typeof maybeResponse?.status === 'number') {
+ return maybeResponse.status
+ }
+
+ const maybeStatus = (error as { status?: number }).status
+ if (typeof maybeStatus === 'number') {
+ return maybeStatus
+ }
+ }
+
+ return null
+}
diff --git a/frontend/layouts/default.vue b/frontend/layouts/default.vue
new file mode 100644
index 0000000..2b33892
--- /dev/null
+++ b/frontend/layouts/default.vue
@@ -0,0 +1,38 @@
+
+
+
diff --git a/frontend/nuxt.config.ts b/frontend/nuxt.config.ts
index a8e3e7a..4fc53d1 100644
--- a/frontend/nuxt.config.ts
+++ b/frontend/nuxt.config.ts
@@ -3,6 +3,11 @@ export default defineNuxtConfig({
devtools: { enabled: true },
ssr: false,
modules: ['@nuxtjs/tailwindcss'],
+ runtimeConfig: {
+ public: {
+ apiBase: process.env.NUXT_PUBLIC_API_BASE
+ }
+ },
typescript: {
strict: true
}
diff --git a/frontend/tailwind.config.ts b/frontend/tailwind.config.ts
new file mode 100644
index 0000000..c5beb37
--- /dev/null
+++ b/frontend/tailwind.config.ts
@@ -0,0 +1,22 @@
+import type { Config } from 'tailwindcss'
+
+export default >{
+ theme: {
+ extend: {
+ colors: {
+ primary: {
+ 50: '#f6f9ea',
+ 100: '#eaf2cf',
+ 200: '#d6e3a4',
+ 300: '#c1d47a',
+ 400: '#afc85a',
+ 500: '#9ebb43',
+ 600: '#7e9735',
+ 700: '#607228',
+ 800: '#414d1a',
+ 900: '#24290d'
+ }
+ }
+ }
+ }
+}