diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d70bb9c --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules +dist +.DS_Store +*.local diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e9e30dc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM node:22-alpine AS builder +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +RUN npm run build + +FROM nginx:alpine +COPY --from=builder /app/dist /usr/share/nginx/html +COPY nginx.conf /etc/nginx/conf.d/default.conf +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/index.html b/index.html new file mode 100644 index 0000000..a5dc35b --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + FluxKit + + + +
+ + + diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..6d0c113 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,10 @@ +server { + listen 80; + server_name localhost; + root /usr/share/nginx/html; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..3a50538 --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "fluxkit", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "vue": "^3.4.0", + "vue-router": "^4.2.0", + "vue-i18n": "^9.9.0", + "pinia": "^2.1.0", + "primevue": "^4.2.0", + "@primevue/themes": "^4.2.0", + "primeicons": "^7.0.0" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.0", + "vite": "^5.4.0", + "tailwindcss": "^3.4.0", + "postcss": "^8.4.0", + "autoprefixer": "^10.4.0" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..2e7af2b --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..acd132f --- /dev/null +++ b/src/App.vue @@ -0,0 +1,51 @@ + + + diff --git a/src/assets/main.css b/src/assets/main.css new file mode 100644 index 0000000..d0267e0 --- /dev/null +++ b/src/assets/main.css @@ -0,0 +1,19 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + --color-bg: #ffffff; + --color-text: #1a1a1a; +} + +.dark { + --color-bg: #1a1a1a; + --color-text: #ffffff; +} + +body { + background-color: var(--color-bg); + color: var(--color-text); + transition: background-color 0.3s, color 0.3s; +} diff --git a/src/i18n.js b/src/i18n.js new file mode 100644 index 0000000..c825917 --- /dev/null +++ b/src/i18n.js @@ -0,0 +1,10 @@ +import { createI18n } from 'vue-i18n' +import de from './locales/de.json' +import en from './locales/en.json' + +export default createI18n({ + legacy: false, + locale: localStorage.getItem('locale') || 'de', + fallbackLocale: 'en', + messages: { de, en } +}) diff --git a/src/locales/de.json b/src/locales/de.json new file mode 100644 index 0000000..169b09a --- /dev/null +++ b/src/locales/de.json @@ -0,0 +1,26 @@ +{ + "nav": { + "home": "Startseite", + "about": "Über uns", + "contact": "Kontakt" + }, + "hero": { + "title": "Willkommen bei FluxKit", + "subtitle": "Die moderne Lösung für Ihre digitalen Projekte", + "cta": "Jetzt starten" + }, + "features": { + "title": "Unsere Features", + "fast": "Blitzschnell", + "fastDesc": "Optimierte Performance für beste Nutzererfahrung", + "secure": "Sicher", + "secureDesc": "Höchste Sicherheitsstandards für Ihre Daten", + "modern": "Modern", + "modernDesc": "Neueste Technologien für zukunftssichere Lösungen" + }, + "theme": { + "light": "Hell", + "dark": "Dunkel" + }, + "language": "Sprache" +} diff --git a/src/locales/en.json b/src/locales/en.json new file mode 100644 index 0000000..59f0145 --- /dev/null +++ b/src/locales/en.json @@ -0,0 +1,26 @@ +{ + "nav": { + "home": "Home", + "about": "About", + "contact": "Contact" + }, + "hero": { + "title": "Welcome to FluxKit", + "subtitle": "The modern solution for your digital projects", + "cta": "Get Started" + }, + "features": { + "title": "Our Features", + "fast": "Lightning Fast", + "fastDesc": "Optimized performance for the best user experience", + "secure": "Secure", + "secureDesc": "Highest security standards for your data", + "modern": "Modern", + "modernDesc": "Latest technologies for future-proof solutions" + }, + "theme": { + "light": "Light", + "dark": "Dark" + }, + "language": "Language" +} diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..431bd36 --- /dev/null +++ b/src/main.js @@ -0,0 +1,29 @@ +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import PrimeVue from 'primevue/config' +import Aura from '@primevue/themes/aura' +import ToastService from 'primevue/toastservice' + +import App from './App.vue' +import router from './router' +import i18n from './i18n' + +import 'primeicons/primeicons.css' +import './assets/main.css' + +const app = createApp(App) + +app.use(createPinia()) +app.use(router) +app.use(i18n) +app.use(PrimeVue, { + theme: { + preset: Aura, + options: { + darkModeSelector: '.dark' + } + } +}) +app.use(ToastService) + +app.mount('#app') diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..bb57748 --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,13 @@ +import { createRouter, createWebHistory } from 'vue-router' +import HomeView from '../views/HomeView.vue' + +const router = createRouter({ + history: createWebHistory(), + routes: [ + { path: '/', name: 'home', component: HomeView }, + { path: '/about', name: 'about', component: () => import('../views/AboutView.vue') }, + { path: '/contact', name: 'contact', component: () => import('../views/ContactView.vue') } + ] +}) + +export default router diff --git a/src/stores/theme.js b/src/stores/theme.js new file mode 100644 index 0000000..068cfef --- /dev/null +++ b/src/stores/theme.js @@ -0,0 +1,17 @@ +import { defineStore } from 'pinia' +import { ref, watch } from 'vue' + +export const useThemeStore = defineStore('theme', () => { + const isDark = ref(localStorage.getItem('theme') === 'dark') + + const toggle = () => { + isDark.value = !isDark.value + } + + watch(isDark, (val) => { + localStorage.setItem('theme', val ? 'dark' : 'light') + document.documentElement.classList.toggle('dark', val) + }, { immediate: true }) + + return { isDark, toggle } +}) diff --git a/src/views/AboutView.vue b/src/views/AboutView.vue new file mode 100644 index 0000000..28c06c5 --- /dev/null +++ b/src/views/AboutView.vue @@ -0,0 +1,17 @@ + + + diff --git a/src/views/ContactView.vue b/src/views/ContactView.vue new file mode 100644 index 0000000..b8e5244 --- /dev/null +++ b/src/views/ContactView.vue @@ -0,0 +1,16 @@ + + + diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue new file mode 100644 index 0000000..b584304 --- /dev/null +++ b/src/views/HomeView.vue @@ -0,0 +1,52 @@ + + + diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..c5f554f --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,12 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: [ + "./index.html", + "./src/**/*.{vue,js,ts,jsx,tsx}", + ], + darkMode: 'class', + theme: { + extend: {}, + }, + plugins: [], +} diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..70ac6e7 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,11 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +export default defineConfig({ + plugins: [vue()], + resolve: { + alias: { + '@': '/src' + } + } +})