first commit
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
.env
|
||||
.vscode/*
|
||||
49
Dockerfile
Normal file
@ -0,0 +1,49 @@
|
||||
# Stage 1: Build (Erstellung des Produktionsbundles)
|
||||
FROM node:20-alpine AS build
|
||||
|
||||
# Setze das Arbeitsverzeichnis
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Kopiere package.json und package-lock.json und installiere die Abhängigkeiten
|
||||
COPY package.json ./
|
||||
RUN npm install --force && npm cache clean --force
|
||||
|
||||
# Kopiere die weiteren wichtigen Projektdateien
|
||||
|
||||
COPY components.json .
|
||||
COPY eslint.config.js .
|
||||
COPY index.html .
|
||||
COPY postcss.config.js .
|
||||
COPY tailwind.config.ts .
|
||||
COPY tsconfig.app.json .
|
||||
COPY tsconfig.json .
|
||||
COPY tsconfig.node.json .
|
||||
COPY vite.config.ts .
|
||||
COPY src ./src
|
||||
COPY public ./public
|
||||
COPY .env .
|
||||
# Baue das Projekt für die Produktion
|
||||
RUN npm run build
|
||||
|
||||
# Stage 2: Production (Einfacher Webserver für die bereitgestellten Dateien)
|
||||
FROM node:20-alpine AS production
|
||||
|
||||
# Setze das Arbeitsverzeichnis
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Installiere ein einfaches Static File Hosting Tool (wie serve)
|
||||
RUN npm install -g serve
|
||||
|
||||
# Kopiere die gebauten Dateien aus der Build-Phase
|
||||
COPY --from=build /usr/src/app/dist ./dist
|
||||
|
||||
# Kopiere die generierte index.html aus dem Build-Ordner (aus der Build-Phase)
|
||||
COPY --from=build /usr/src/app/index.html ./index.html
|
||||
# Baue die TypeScript API
|
||||
#RUN npm install && npx tsc api.ts
|
||||
|
||||
# Exponiere den Port, auf dem der Server läuft
|
||||
EXPOSE 5030
|
||||
|
||||
# Starte den Server auf Port 5000 (dieser wird dann über den Nginx-Reverse-Proxy weitergeleitet)
|
||||
CMD ["serve", "-s", "dist", "-l", "5030"]
|
||||
218
api_doku.md
Normal file
@ -0,0 +1,218 @@
|
||||
# REST API Übersicht (aus Client-Calls im Projekt abgeleitet)
|
||||
|
||||
- **Base URL**: `VITE_WEBHOOK_URL` (siehe `src/lib/config.ts -> getWebhookUrl()`)
|
||||
- **Auth**:
|
||||
- Cookies werden standardmäßig mitgesendet (`credentials: 'include'`)
|
||||
- Falls vorhanden wird `Authorization: Bearer <token>` gesetzt (siehe `apiFetch`)
|
||||
- Bei `401` wird automatisch Refresh versucht über `/auth/rnjwt`
|
||||
|
||||
## Auth
|
||||
|
||||
- **POST /auth_login**
|
||||
- Headers: `Content-Type: application/json`
|
||||
- Body:
|
||||
```json
|
||||
{ "email": "string", "password": "string" }
|
||||
```
|
||||
- Response:
|
||||
```json
|
||||
{ "token": "string", "user": { ... } }
|
||||
```
|
||||
|
||||
- **GET /auth/rnjwt**
|
||||
- Zweck: JWT Refresh
|
||||
- Response:
|
||||
```json
|
||||
{ "token": "string" }
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
- **POST /event/new_manual**
|
||||
- Headers: `Content-Type: application/json`
|
||||
- Body:
|
||||
```json
|
||||
{
|
||||
"name": "string",
|
||||
"description": "string?",
|
||||
"location": "string?",
|
||||
"url": "string?",
|
||||
"image": "string?",
|
||||
"manager_name": "string?",
|
||||
"manager_email": "string?",
|
||||
"begin_date": "YYYY-MM-DD?",
|
||||
"end_date": "YYYY-MM-DD?"
|
||||
}
|
||||
```
|
||||
- Response: beliebiges Event-Objekt
|
||||
|
||||
- **GET /events/get_current**
|
||||
- Response: `Event[]` oder ein einzelnes Event-Objekt
|
||||
|
||||
- **GET /events**
|
||||
- Response: `Event[]` oder ein einzelnes Event-Objekt
|
||||
|
||||
- **POST /event/new_fromurl**
|
||||
- Headers: `Content-Type: application/json`
|
||||
- Body:
|
||||
```json
|
||||
{ "url": "string", "command": "eventmodus_extract_from_url" }
|
||||
```
|
||||
- Response: `data.message_from_ai` oder Roh-Response
|
||||
|
||||
## Blog
|
||||
|
||||
- **GET /blog/new_blog**
|
||||
- Response:
|
||||
```json
|
||||
{ "id": "string" } // oder { "blog_id": "string" }
|
||||
```
|
||||
|
||||
- **POST /blog/publish**
|
||||
- Headers: `Content-Type: application/json`
|
||||
- Body:
|
||||
```json
|
||||
{
|
||||
"blog_id": "string",
|
||||
"publish_date": "YYYY-MM-DD",
|
||||
"publish_socialmedia": true,
|
||||
"socialmedia_channels": ["string"],
|
||||
"socialmedia_languages": ["string"]
|
||||
}
|
||||
```
|
||||
- Response: beliebige Publikations-Infos
|
||||
|
||||
- **POST /blog/update**
|
||||
- Headers: `Content-Type: application/json`
|
||||
- Body:
|
||||
```json
|
||||
{
|
||||
"blog_id": "string",
|
||||
"content": { ... }
|
||||
}
|
||||
```
|
||||
- Response: Update-Ergebnis
|
||||
|
||||
- **POST /blog/generate**
|
||||
- Headers: `Content-Type: application/json`
|
||||
- Body:
|
||||
```json
|
||||
{
|
||||
"blog_Id": "string",
|
||||
"topic": "string",
|
||||
"tonality": "string",
|
||||
"languages": ["string"]
|
||||
}
|
||||
```
|
||||
- Response: generierter Blog-Content
|
||||
|
||||
- **GET /blog/topic_suggestion**
|
||||
- Response:
|
||||
```json
|
||||
{ "topics": ["string", ...] } | ["string", ...]
|
||||
```
|
||||
|
||||
## Dateien & Medien
|
||||
|
||||
- **POST /file_upload_blog**
|
||||
- Body (FormData):
|
||||
- `file`: File
|
||||
- `blog_id`: string
|
||||
- Response:
|
||||
```json
|
||||
{ "url": "string", ... }
|
||||
```
|
||||
|
||||
- **POST /file_upload_event**
|
||||
- Body (FormData):
|
||||
- `file`: File
|
||||
- `event_id`: string
|
||||
- Response:
|
||||
```json
|
||||
{ "url": "string", ... }
|
||||
```
|
||||
|
||||
- **POST /upload_tmp**
|
||||
- Body (FormData):
|
||||
- `file`: File
|
||||
- Response:
|
||||
```json
|
||||
{ "url": "string", ... }
|
||||
```
|
||||
|
||||
- **POST /media/image_generator**
|
||||
- Headers: `Content-Type: application/json`
|
||||
- Body:
|
||||
```json
|
||||
{ "blog_id": "string", "title": "string" }
|
||||
```
|
||||
- Response:
|
||||
```json
|
||||
{ "url": "string" } // oder { "imageUrl": "string" }
|
||||
```
|
||||
|
||||
- Hinweis: `generateAIImage` ruft aktuell
|
||||
- **POST /file_upload**
|
||||
- Headers: `Content-Type: application/json`
|
||||
- Body:
|
||||
```json
|
||||
{ "prompt": "string" }
|
||||
```
|
||||
- Response:
|
||||
```json
|
||||
{ "imageUrl": "string", ... }
|
||||
```
|
||||
- Anmerkung: Endpoint-Name wirkt untypisch für Image-Generation.
|
||||
|
||||
## Tools
|
||||
|
||||
- **POST /tools/speech2text**
|
||||
- Body (FormData):
|
||||
- `file`: Audio-Datei
|
||||
- Response:
|
||||
```json
|
||||
{ "transcription": "string" } // oder "text", "result"
|
||||
```
|
||||
|
||||
## Social Media
|
||||
|
||||
- **POST /socialmedia/post2event**
|
||||
- Headers: `Content-Type: application/json`
|
||||
- Body: frei, je nach Nutzungsfall (Payload für Generierung)
|
||||
- Response: generierte Posts
|
||||
|
||||
- **POST /socialmedia/publish_post**
|
||||
- Headers: `Content-Type: application/json`
|
||||
- Body:
|
||||
```json
|
||||
{
|
||||
"postId": "string",
|
||||
"posts": { ... },
|
||||
"images": { ... },
|
||||
"scheduledTime": "string"
|
||||
}
|
||||
```
|
||||
- Response: Veröffentlichungs-Ergebnis
|
||||
|
||||
## Gemeinsame Aspekte
|
||||
|
||||
- **Headers**
|
||||
- `Content-Type: application/json` bei JSON-Requests
|
||||
- FormData-Uploads ohne explizites `Content-Type` (Browser setzt Multi‑Part)
|
||||
- **Auth**
|
||||
- Cookies via `credentials: 'include'`
|
||||
- Optionaler Bearer-Token via `Authorization`
|
||||
- Auto-Refresh bei 401 über `/auth/rnjwt`, danach Retry
|
||||
- **Statuscodes**
|
||||
- Client erwartet `response.ok === true` bei Erfolg, sonst Fehlerwurf
|
||||
- **Variabilität**
|
||||
- Einige Responses sind polymorph (Array oder Objekt). Umgang entsprechend im Client.
|
||||
|
||||
# Beispiel: apiFetch Verhalten
|
||||
|
||||
- Sendet automatisch Cookies
|
||||
- Fügt `Authorization: Bearer <token>` hinzu, wenn verfügbar
|
||||
- Bei 401:
|
||||
- versucht `GET /auth/rnjwt`
|
||||
- wiederholt Request mit neuem Token
|
||||
- bei erneutem 401: Logout und Fehlermeldung
|
||||
20
components.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "default",
|
||||
"rsc": false,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.ts",
|
||||
"css": "src/index.css",
|
||||
"baseColor": "slate",
|
||||
"cssVariables": true,
|
||||
"prefix": ""
|
||||
},
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils",
|
||||
"ui": "@/components/ui",
|
||||
"lib": "@/lib",
|
||||
"hooks": "@/hooks"
|
||||
}
|
||||
}
|
||||
23
deploy.sh
Normal file
@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Setze die Docker-Compose-Datei
|
||||
COMPOSE_FILE="/home/martin/docker/apps/kimaschine.assistent/docker-compose.yml"
|
||||
|
||||
|
||||
# Docker-Container herunterfahren
|
||||
echo "🛑 Stopping Docker containers..."
|
||||
docker-compose -f $COMPOSE_FILE down --remove-orphans
|
||||
|
||||
# Git-Pull mit Benutzername und Passwort
|
||||
echo "📂 Pulling latest changes from Git..."
|
||||
git pull
|
||||
|
||||
# Docker-Image neu bauen
|
||||
echo "🔨 Rebuilding Docker image without cache..."
|
||||
docker-compose -f $COMPOSE_FILE build --no-cache
|
||||
|
||||
# Docker-Container wieder hochfahren
|
||||
echo "🚀 Starting Docker containers..."
|
||||
docker-compose -f $COMPOSE_FILE up -d
|
||||
|
||||
echo "✅ Workflow completed!"
|
||||
BIN
dist/Logo.png
vendored
Normal file
|
After Width: | Height: | Size: 68 KiB |
191
dist/assets/index-CzGVSrN-.js
vendored
Normal file
1
dist/assets/index-DHgMgX29.css
vendored
Normal file
BIN
dist/default_event.png
vendored
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
dist/favicon/android-icon-144x144.png
vendored
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
dist/favicon/android-icon-192x192.png
vendored
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
dist/favicon/android-icon-36x36.png
vendored
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
dist/favicon/android-icon-48x48.png
vendored
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
dist/favicon/android-icon-72x72.png
vendored
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
dist/favicon/android-icon-96x96.png
vendored
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
dist/favicon/apple-icon-114x114.png
vendored
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
dist/favicon/apple-icon-120x120.png
vendored
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
dist/favicon/apple-icon-144x144.png
vendored
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
dist/favicon/apple-icon-152x152.png
vendored
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
dist/favicon/apple-icon-180x180.png
vendored
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
dist/favicon/apple-icon-57x57.png
vendored
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
dist/favicon/apple-icon-60x60.png
vendored
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
dist/favicon/apple-icon-72x72.png
vendored
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
dist/favicon/apple-icon-76x76.png
vendored
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
dist/favicon/apple-icon-precomposed.png
vendored
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
dist/favicon/apple-icon.png
vendored
Normal file
|
After Width: | Height: | Size: 34 KiB |
2
dist/favicon/browserconfig.xml
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>
|
||||
BIN
dist/favicon/favicon-16x16.png
vendored
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
dist/favicon/favicon-32x32.png
vendored
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
dist/favicon/favicon-96x96.png
vendored
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
dist/favicon/favicon.ico
vendored
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
41
dist/favicon/manifest.json
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "App",
|
||||
"icons": [
|
||||
{
|
||||
"src": "\/android-icon-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
dist/favicon/ms-icon-144x144.png
vendored
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
dist/favicon/ms-icon-150x150.png
vendored
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
dist/favicon/ms-icon-310x310.png
vendored
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
dist/favicon/ms-icon-70x70.png
vendored
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
dist/images/ITTools.jpeg
vendored
Normal file
|
After Width: | Height: | Size: 157 KiB |
BIN
dist/images/robo/robo_blogauthor.png
vendored
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
dist/images/robo/robo_event.png
vendored
Normal file
|
After Width: | Height: | Size: 186 KiB |
BIN
dist/images/sales.jpeg
vendored
Normal file
|
After Width: | Height: | Size: 107 KiB |
BIN
dist/images/webhero.jpeg
vendored
Normal file
|
After Width: | Height: | Size: 177 KiB |
93
dist/index.html
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>K.I. Maschine</title>
|
||||
<meta name="description" content="KIMaschine.de" />
|
||||
<meta name="author" content="KIMaschine.de" />
|
||||
|
||||
<meta property="og:title" content="K.I. Maschine.de" />
|
||||
<meta property="og:description" content="KImaschine automates your website, blog, and social media content using advanced AI. Save time, boost efficiency, and stay ahead in the digital competition." />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="https://kimaschine.de/logo.png" />
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:site" content="@KIMaschine_de" />
|
||||
<meta name="twitter:image" content="https://kimaschine.de/logo.png" />
|
||||
|
||||
<!-- Favicon links -->
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" sizes="36x36" href="/favicon/android-icon-36x36.png">
|
||||
<link rel="icon" type="image/png" sizes="48x48" href="/favicon/android-icon-48x48.png">
|
||||
<link rel="icon" type="image/png" sizes="72x72" href="/favicon/android-icon-72x72.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="/favicon/android-icon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="144x144" href="/favicon/android-icon-144x144.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/favicon/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="/favicon/favicon-96x96.png">
|
||||
<link rel="shortcut icon" href="/favicon/favicon.ico">
|
||||
<link rel="manifest" href="/favicon/manifest.json">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="/favicon/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<script type="module" crossorigin src="/assets/index-CzGVSrN-.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-DHgMgX29.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<!-- IMPORTANT: DO NOT REMOVE THIS SCRIPT TAG OR THIS VERY COMMENT! -->
|
||||
<!-- <script src="https://cdn.gpteng.co/gptengineer.js" type="module"></script> -->
|
||||
<!-- Metricool Tracking -->
|
||||
<!-- <script>
|
||||
function loadScript(a){
|
||||
var b=document.getElementsByTagName("head")[0],
|
||||
c=document.createElement("script");
|
||||
c.type="text/javascript",
|
||||
c.src="https://tracker.metricool.com/resources/be.js",
|
||||
c.onreadystatechange=a,
|
||||
c.onload=a,
|
||||
b.appendChild(c)
|
||||
}
|
||||
loadScript(function(){
|
||||
beTracker.t({hash:"9496eca8438c4d21471232f7b1bf962f"})
|
||||
});
|
||||
</script> -->
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<meta property="og:title" content="KIMaschine.de" />
|
||||
<meta property="og:description" content="KIMaschine.de" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="https://kimaschinede.vercel.app/logo.png" />
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:site" content="@KIMaschine_de" />
|
||||
<meta name="twitter:image" content="https://kimaschinede.vercel.app/logo.png" />
|
||||
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="favicon/apple-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="favicon/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="favicon/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="favicon/apple-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="favicon/apple-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="favicon/apple-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="favicon/apple-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="favicon/apple-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="favicon/apple-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="favicon/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="favicon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="favicon/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="favicon/favicon-16x16.png">
|
||||
<link rel="manifest" href="/favicon/manifest.json">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="favicon/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
BIN
dist/lovable-uploads/1396093b-9357-4118-8305-776ac2bf90b8.png
vendored
Normal file
|
After Width: | Height: | Size: 61 KiB |
BIN
dist/lovable-uploads/2acd3368-2b93-4913-8041-5151b626a0cd.png
vendored
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
dist/martin.jpeg
vendored
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
dist/miguel.jpeg
vendored
Normal file
|
After Width: | Height: | Size: 40 KiB |
1
dist/placeholder.svg
vendored
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1200" fill="none"><rect width="1200" height="1200" fill="#EAEAEA" rx="3"/><g opacity=".5"><g opacity=".5"><path fill="#FAFAFA" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/></g><path stroke="url(#a)" stroke-width="2.418" d="M0-1.209h553.581" transform="scale(1 -1) rotate(45 1163.11 91.165)"/><path stroke="url(#b)" stroke-width="2.418" d="M404.846 598.671h391.726"/><path stroke="url(#c)" stroke-width="2.418" d="M599.5 795.742V404.017"/><path stroke="url(#d)" stroke-width="2.418" d="m795.717 796.597-391.441-391.44"/><path fill="#fff" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/><g clip-path="url(#e)"><path fill="#666" fill-rule="evenodd" d="M616.426 586.58h-31.434v16.176l3.553-3.554.531-.531h9.068l.074-.074 8.463-8.463h2.565l7.18 7.181V586.58Zm-15.715 14.654 3.698 3.699 1.283 1.282-2.565 2.565-1.282-1.283-5.2-5.199h-6.066l-5.514 5.514-.073.073v2.876a2.418 2.418 0 0 0 2.418 2.418h26.598a2.418 2.418 0 0 0 2.418-2.418v-8.317l-8.463-8.463-7.181 7.181-.071.072Zm-19.347 5.442v4.085a6.045 6.045 0 0 0 6.046 6.045h26.598a6.044 6.044 0 0 0 6.045-6.045v-7.108l1.356-1.355-1.282-1.283-.074-.073v-17.989h-38.689v23.43l-.146.146.146.147Z" clip-rule="evenodd"/></g><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/></g><defs><linearGradient id="a" x1="554.061" x2="-.48" y1=".083" y2=".087" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="b" x1="796.912" x2="404.507" y1="599.963" y2="599.965" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="c" x1="600.792" x2="600.794" y1="403.677" y2="796.082" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="d" x1="404.85" x2="796.972" y1="403.903" y2="796.02" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><clipPath id="e"><path fill="#fff" d="M581.364 580.535h38.689v38.689h-38.689z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
14
dist/robots.txt
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
User-agent: Googlebot
|
||||
Allow: /
|
||||
|
||||
User-agent: Bingbot
|
||||
Allow: /
|
||||
|
||||
User-agent: Twitterbot
|
||||
Allow: /
|
||||
|
||||
User-agent: facebookexternalhit
|
||||
Allow: /
|
||||
|
||||
User-agent: *
|
||||
Allow: /
|
||||
0
dist/test.svg
vendored
Normal file
29
eslint.config.js
Normal file
@ -0,0 +1,29 @@
|
||||
import js from "@eslint/js";
|
||||
import globals from "globals";
|
||||
import reactHooks from "eslint-plugin-react-hooks";
|
||||
import reactRefresh from "eslint-plugin-react-refresh";
|
||||
import tseslint from "typescript-eslint";
|
||||
|
||||
export default tseslint.config(
|
||||
{ ignores: ["dist"] },
|
||||
{
|
||||
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
||||
files: ["**/*.{ts,tsx}"],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
globals: globals.browser,
|
||||
},
|
||||
plugins: {
|
||||
"react-hooks": reactHooks,
|
||||
"react-refresh": reactRefresh,
|
||||
},
|
||||
rules: {
|
||||
...reactHooks.configs.recommended.rules,
|
||||
"react-refresh/only-export-components": [
|
||||
"warn",
|
||||
{ allowConstantExport: true },
|
||||
],
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
},
|
||||
}
|
||||
);
|
||||
1
google0a5a3eb63f61c0ea.html
Normal file
@ -0,0 +1 @@
|
||||
google-site-verification: google0a5a3eb63f61c0ea.html
|
||||
92
index.html
Normal file
@ -0,0 +1,92 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>K.I. Maschine</title>
|
||||
<meta name="description" content="KIMaschine.de" />
|
||||
<meta name="author" content="KIMaschine.de" />
|
||||
|
||||
<meta property="og:title" content="K.I. Maschine.de" />
|
||||
<meta property="og:description" content="KImaschine automates your website, blog, and social media content using advanced AI. Save time, boost efficiency, and stay ahead in the digital competition." />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="https://kimaschine.de/logo.png" />
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:site" content="@KIMaschine_de" />
|
||||
<meta name="twitter:image" content="https://kimaschine.de/logo.png" />
|
||||
|
||||
<!-- Favicon links -->
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" sizes="36x36" href="/favicon/android-icon-36x36.png">
|
||||
<link rel="icon" type="image/png" sizes="48x48" href="/favicon/android-icon-48x48.png">
|
||||
<link rel="icon" type="image/png" sizes="72x72" href="/favicon/android-icon-72x72.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="/favicon/android-icon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="144x144" href="/favicon/android-icon-144x144.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/favicon/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="/favicon/favicon-96x96.png">
|
||||
<link rel="shortcut icon" href="/favicon/favicon.ico">
|
||||
<link rel="manifest" href="/favicon/manifest.json">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="/favicon/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<!-- IMPORTANT: DO NOT REMOVE THIS SCRIPT TAG OR THIS VERY COMMENT! -->
|
||||
<!-- <script src="https://cdn.gpteng.co/gptengineer.js" type="module"></script> -->
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
<!-- Metricool Tracking -->
|
||||
<!-- <script>
|
||||
function loadScript(a){
|
||||
var b=document.getElementsByTagName("head")[0],
|
||||
c=document.createElement("script");
|
||||
c.type="text/javascript",
|
||||
c.src="https://tracker.metricool.com/resources/be.js",
|
||||
c.onreadystatechange=a,
|
||||
c.onload=a,
|
||||
b.appendChild(c)
|
||||
}
|
||||
loadScript(function(){
|
||||
beTracker.t({hash:"9496eca8438c4d21471232f7b1bf962f"})
|
||||
});
|
||||
</script> -->
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<meta property="og:title" content="KIMaschine.de" />
|
||||
<meta property="og:description" content="KIMaschine.de" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="https://kimaschinede.vercel.app/logo.png" />
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:site" content="@KIMaschine_de" />
|
||||
<meta name="twitter:image" content="https://kimaschinede.vercel.app/logo.png" />
|
||||
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="favicon/apple-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="favicon/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="favicon/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="favicon/apple-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="favicon/apple-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="favicon/apple-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="favicon/apple-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="favicon/apple-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="favicon/apple-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="favicon/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="favicon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="favicon/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="favicon/favicon-16x16.png">
|
||||
<link rel="manifest" href="/favicon/manifest.json">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="favicon/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
10453
package-lock.json
generated
Normal file
101
package.json
Normal file
@ -0,0 +1,101 @@
|
||||
{
|
||||
"name": "vite_react_shadcn_ts",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"build:dev": "vite build --mode development",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview",
|
||||
"test": "vitest",
|
||||
"test:watch": "vitest --watch",
|
||||
"coverage": "vitest run --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hookform/resolvers": "^3.9.0",
|
||||
"@radix-ui/react-accordion": "^1.2.0",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.1",
|
||||
"@radix-ui/react-aspect-ratio": "^1.1.0",
|
||||
"@radix-ui/react-avatar": "^1.1.0",
|
||||
"@radix-ui/react-checkbox": "^1.1.1",
|
||||
"@radix-ui/react-collapsible": "^1.1.0",
|
||||
"@radix-ui/react-context-menu": "^2.2.1",
|
||||
"@radix-ui/react-dialog": "^1.1.2",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||
"@radix-ui/react-hover-card": "^1.1.1",
|
||||
"@radix-ui/react-icons": "^1.3.2",
|
||||
"@radix-ui/react-label": "^2.1.0",
|
||||
"@radix-ui/react-menubar": "^1.1.1",
|
||||
"@radix-ui/react-navigation-menu": "^1.2.0",
|
||||
"@radix-ui/react-popover": "^1.1.1",
|
||||
"@radix-ui/react-progress": "^1.1.0",
|
||||
"@radix-ui/react-radio-group": "^1.2.0",
|
||||
"@radix-ui/react-scroll-area": "^1.1.0",
|
||||
"@radix-ui/react-select": "^2.1.1",
|
||||
"@radix-ui/react-separator": "^1.1.0",
|
||||
"@radix-ui/react-slider": "^1.2.0",
|
||||
"@radix-ui/react-slot": "^1.1.0",
|
||||
"@radix-ui/react-switch": "^1.1.0",
|
||||
"@radix-ui/react-tabs": "^1.1.12",
|
||||
"@radix-ui/react-toast": "^1.2.1",
|
||||
"@radix-ui/react-toggle": "^1.1.0",
|
||||
"@radix-ui/react-toggle-group": "^1.1.0",
|
||||
"@radix-ui/react-tooltip": "^1.1.4",
|
||||
"@tanstack/react-query": "^5.56.2",
|
||||
"@types/react-dropzone": "^4.2.2",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.0.0",
|
||||
"date-fns": "^3.6.0",
|
||||
"embla-carousel-react": "^8.3.0",
|
||||
"input-otp": "^1.2.4",
|
||||
"lucide-react": "^0.462.0",
|
||||
"next-themes": "^0.3.0",
|
||||
"react": "^18.3.1",
|
||||
"react-day-picker": "^9.7.0",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-dropzone": "^14.3.8",
|
||||
"react-easy-crop": "^5.5.6",
|
||||
"react-helmet-async": "^2.0.5",
|
||||
"react-hook-form": "^7.53.0",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-quill": "^2.0.0",
|
||||
"react-resizable-panels": "^2.1.3",
|
||||
"react-router-dom": "^6.26.2",
|
||||
"react-swipeable": "^7.0.2",
|
||||
"recharts": "^2.12.7",
|
||||
"sonner": "^1.5.0",
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"vaul": "^0.9.3",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.9.0",
|
||||
"@tailwindcss/typography": "^0.5.15",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/react": "^16.0.1",
|
||||
"@testing-library/user-event": "^14.5.2",
|
||||
"@types/node": "^22.5.5",
|
||||
"@types/react": "^18.3.23",
|
||||
"@types/react-dom": "^18.3.7",
|
||||
"@vitejs/plugin-react": "^4.5.0",
|
||||
"@vitejs/plugin-react-swc": "^3.5.0",
|
||||
"@vitest/coverage-v8": "^2.1.9",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^9.9.0",
|
||||
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.9",
|
||||
"globals": "^15.9.0",
|
||||
"jsdom": "^25.0.1",
|
||||
"lovable-tagger": "^1.1.7",
|
||||
"postcss": "^8.4.47",
|
||||
"tailwindcss": "^3.4.11",
|
||||
"typescript": "^5.5.3",
|
||||
"typescript-eslint": "^8.0.1",
|
||||
"vite": "^5.4.1",
|
||||
"vitest": "^2.1.1"
|
||||
}
|
||||
}
|
||||
6
postcss.config.js
Normal file
@ -0,0 +1,6 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
BIN
public/Logo.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
public/default_event.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
public/favicon/android-icon-144x144.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
public/favicon/android-icon-192x192.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
public/favicon/android-icon-36x36.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
public/favicon/android-icon-48x48.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
public/favicon/android-icon-72x72.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
public/favicon/android-icon-96x96.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/favicon/apple-icon-114x114.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
public/favicon/apple-icon-120x120.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/favicon/apple-icon-144x144.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
public/favicon/apple-icon-152x152.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
public/favicon/apple-icon-180x180.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
public/favicon/apple-icon-57x57.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
public/favicon/apple-icon-60x60.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
public/favicon/apple-icon-72x72.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
public/favicon/apple-icon-76x76.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
public/favicon/apple-icon-precomposed.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
public/favicon/apple-icon.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
2
public/favicon/browserconfig.xml
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>
|
||||
BIN
public/favicon/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
public/favicon/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
public/favicon/favicon-96x96.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/favicon/favicon.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
41
public/favicon/manifest.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "App",
|
||||
"icons": [
|
||||
{
|
||||
"src": "\/android-icon-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
public/favicon/ms-icon-144x144.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
public/favicon/ms-icon-150x150.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
public/favicon/ms-icon-310x310.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
public/favicon/ms-icon-70x70.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
public/images/ITTools.jpeg
Normal file
|
After Width: | Height: | Size: 157 KiB |
BIN
public/images/robo/robo_blogauthor.png
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
public/images/robo/robo_event.png
Normal file
|
After Width: | Height: | Size: 186 KiB |
BIN
public/images/sales.jpeg
Normal file
|
After Width: | Height: | Size: 107 KiB |
BIN
public/images/webhero.jpeg
Normal file
|
After Width: | Height: | Size: 177 KiB |
BIN
public/kgblogo.png
Normal file
|
After Width: | Height: | Size: 107 KiB |
BIN
public/lovable-uploads/1396093b-9357-4118-8305-776ac2bf90b8.png
Normal file
|
After Width: | Height: | Size: 61 KiB |
BIN
public/lovable-uploads/2acd3368-2b93-4913-8041-5151b626a0cd.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
public/martin.jpeg
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
public/miguel.jpeg
Normal file
|
After Width: | Height: | Size: 40 KiB |
1
public/placeholder.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1200" fill="none"><rect width="1200" height="1200" fill="#EAEAEA" rx="3"/><g opacity=".5"><g opacity=".5"><path fill="#FAFAFA" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/></g><path stroke="url(#a)" stroke-width="2.418" d="M0-1.209h553.581" transform="scale(1 -1) rotate(45 1163.11 91.165)"/><path stroke="url(#b)" stroke-width="2.418" d="M404.846 598.671h391.726"/><path stroke="url(#c)" stroke-width="2.418" d="M599.5 795.742V404.017"/><path stroke="url(#d)" stroke-width="2.418" d="m795.717 796.597-391.441-391.44"/><path fill="#fff" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/><g clip-path="url(#e)"><path fill="#666" fill-rule="evenodd" d="M616.426 586.58h-31.434v16.176l3.553-3.554.531-.531h9.068l.074-.074 8.463-8.463h2.565l7.18 7.181V586.58Zm-15.715 14.654 3.698 3.699 1.283 1.282-2.565 2.565-1.282-1.283-5.2-5.199h-6.066l-5.514 5.514-.073.073v2.876a2.418 2.418 0 0 0 2.418 2.418h26.598a2.418 2.418 0 0 0 2.418-2.418v-8.317l-8.463-8.463-7.181 7.181-.071.072Zm-19.347 5.442v4.085a6.045 6.045 0 0 0 6.046 6.045h26.598a6.044 6.044 0 0 0 6.045-6.045v-7.108l1.356-1.355-1.282-1.283-.074-.073v-17.989h-38.689v23.43l-.146.146.146.147Z" clip-rule="evenodd"/></g><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/></g><defs><linearGradient id="a" x1="554.061" x2="-.48" y1=".083" y2=".087" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="b" x1="796.912" x2="404.507" y1="599.963" y2="599.965" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="c" x1="600.792" x2="600.794" y1="403.677" y2="796.082" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="d" x1="404.85" x2="796.972" y1="403.903" y2="796.02" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><clipPath id="e"><path fill="#fff" d="M581.364 580.535h38.689v38.689h-38.689z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
14
public/robots.txt
Normal file
@ -0,0 +1,14 @@
|
||||
User-agent: Googlebot
|
||||
Allow: /
|
||||
|
||||
User-agent: Bingbot
|
||||
Allow: /
|
||||
|
||||
User-agent: Twitterbot
|
||||
Allow: /
|
||||
|
||||
User-agent: facebookexternalhit
|
||||
Allow: /
|
||||
|
||||
User-agent: *
|
||||
Allow: /
|
||||
0
public/test.svg
Normal file
42
src/App.css
Normal file
@ -0,0 +1,42 @@
|
||||
#root {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
transition: filter 300ms;
|
||||
}
|
||||
.logo:hover {
|
||||
filter: drop-shadow(0 0 2em #646cffaa);
|
||||
}
|
||||
.logo.react:hover {
|
||||
filter: drop-shadow(0 0 2em #61dafbaa);
|
||||
}
|
||||
|
||||
@keyframes logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
a:nth-of-type(2) .logo {
|
||||
animation: logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
.read-the-docs {
|
||||
color: #888;
|
||||
}
|
||||
48
src/App.tsx
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
import { Toaster } from "@/components/ui/toaster";
|
||||
import { Toaster as Sonner } from "@/components/ui/sonner";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
||||
import { HelmetProvider } from "react-helmet-async";
|
||||
import { LanguageProvider } from "@/contexts/LanguageContext";
|
||||
import { AuthProvider, useAuth } from "@/contexts/AuthContext";
|
||||
import Main from "./components/app/Main";
|
||||
import LoginContainer from "./components/auth/LoginContainer";
|
||||
import ArtistCollabForm from "@/features/event/components/ArtistCollabForm";
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
const AppContent = () => {
|
||||
const { user } = useAuth();
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/collab/:token" element={<ArtistCollabForm />} />
|
||||
<Route
|
||||
path="/*"
|
||||
element={user ? <Main /> : <LoginContainer />}
|
||||
/>
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
||||
const App = () => (
|
||||
<HelmetProvider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<TooltipProvider>
|
||||
<LanguageProvider>
|
||||
<AuthProvider>
|
||||
<Toaster />
|
||||
<Sonner />
|
||||
<BrowserRouter>
|
||||
<AppContent />
|
||||
</BrowserRouter>
|
||||
</AuthProvider>
|
||||
</LanguageProvider>
|
||||
</TooltipProvider>
|
||||
</QueryClientProvider>
|
||||
</HelmetProvider>
|
||||
);
|
||||
|
||||
export default App;
|
||||
108
src/components/app/Main.tsx
Normal file
@ -0,0 +1,108 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { LogOut, Menu } from 'lucide-react';
|
||||
import { useAuth } from '@/contexts/AuthContext';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import DashboardContainer from '../dashboard/DashboardContainer';
|
||||
import { cn } from '@/lib/utils';
|
||||
const Main: React.FC = () => {
|
||||
const { user, logout } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const [hasActiveEvent, setHasActiveEvent] = useState(false);
|
||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||
|
||||
// Check for active events - This will be replaced with actual API call
|
||||
useEffect(() => {
|
||||
// TODO: Replace with actual API call to check for active events
|
||||
const checkActiveEvents = async () => {
|
||||
try {
|
||||
// const response = await fetch('/api/events/active');
|
||||
// const data = await response.json();
|
||||
// setHasActiveEvent(data.hasActiveEvent);
|
||||
|
||||
// For now, we'll set it to false
|
||||
setHasActiveEvent(false);
|
||||
} catch (error) {
|
||||
console.error('Error checking active events:', error);
|
||||
}
|
||||
};
|
||||
|
||||
checkActiveEvents();
|
||||
}, []);
|
||||
|
||||
const handleAction = (action: string) => {
|
||||
console.log('Selected action:', action);
|
||||
// Handle navigation or other actions based on the selected card
|
||||
switch (action) {
|
||||
case 'event':
|
||||
// Navigate to events page or open event form
|
||||
break;
|
||||
case 'blog':
|
||||
// Navigate to blog page or open blog form
|
||||
break;
|
||||
case 'quick-post':
|
||||
// Open quick post dialog
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* Header */}
|
||||
<header className="sticky top-0 z-40 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
||||
<div className="container flex h-16 items-center justify-between px-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="md:hidden"
|
||||
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||||
>
|
||||
<Menu className="h-5 w-5" />
|
||||
<span className="sr-only">Toggle menu</span>
|
||||
</Button>
|
||||
<div
|
||||
className="flex items-center gap-2 cursor-pointer"
|
||||
onClick={() => navigate('/')}
|
||||
>
|
||||
<img
|
||||
src="/Logo.png"
|
||||
alt="Logo"
|
||||
className="h-10 w-auto object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="hidden md:block text-sm text-muted-foreground">
|
||||
Hallo, {user?.name?.split(' ')[0] || 'Benutzer'}
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="gap-1.5 text-sm"
|
||||
onClick={logout}
|
||||
>
|
||||
<LogOut className="h-4 w-4" />
|
||||
<span className="hidden sm:inline">Abmelden</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* Main Content */}
|
||||
<main className="container py-6 px-0 md:px-4">
|
||||
<div className="mx-auto md:max-w-5xl">
|
||||
<DashboardContainer
|
||||
onActionClick={handleAction}
|
||||
hasActiveEvent={hasActiveEvent}
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Main;
|
||||