production: docker + nginx config for rf-flux.com
Some checks failed
Deploy to VPS / deploy (push) Has been cancelled
19
.dockerignore
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
node_modules
|
||||||
|
.next
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
*.md
|
||||||
|
README*
|
||||||
|
.env*
|
||||||
|
.env
|
||||||
|
docker-compose*.yml
|
||||||
|
Dockerfile
|
||||||
|
nginx/
|
||||||
|
certbot/
|
||||||
|
scripts/
|
||||||
|
prisma/dev.db
|
||||||
|
prisma/dev.db-journal
|
||||||
|
prisma/migrations/migration_lock.toml
|
||||||
|
.DS_Store
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
51
.github/workflows/deploy.yml
vendored
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# FLUX SRL — GitHub Actions Deploy Pipeline
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# Triggers on push to main branch.
|
||||||
|
# Requires GitHub Secrets:
|
||||||
|
# VPS_HOST — Your VPS IP or hostname
|
||||||
|
# SSH_PRIVATE_KEY — ED25519 private key for flux-deploy user
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
name: Deploy to VPS
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 15
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Deploy via SSH
|
||||||
|
uses: appleboy/ssh-action@v1
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.VPS_HOST }}
|
||||||
|
username: flux-deploy
|
||||||
|
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
|
script_stop: true
|
||||||
|
script: |
|
||||||
|
cd /opt/flux-srl
|
||||||
|
|
||||||
|
echo "⏳ Pulling latest code..."
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
|
echo "⏳ Building app container..."
|
||||||
|
docker compose build --no-cache app
|
||||||
|
|
||||||
|
echo "⏳ Restarting app..."
|
||||||
|
docker compose up -d app
|
||||||
|
|
||||||
|
echo "⏳ Running migrations..."
|
||||||
|
docker compose exec -T app npx prisma migrate deploy
|
||||||
|
|
||||||
|
echo "⏳ Cleaning up old images..."
|
||||||
|
docker image prune -f
|
||||||
|
|
||||||
|
echo "⏳ Health check..."
|
||||||
|
sleep 5
|
||||||
|
curl -sf http://localhost/api/health || echo "⚠ Health check failed"
|
||||||
|
|
||||||
|
echo "✅ Deploy complete."
|
||||||
2
.gitignore
vendored
@ -39,3 +39,5 @@ yarn-error.log*
|
|||||||
# typescript
|
# typescript
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
|
|
||||||
|
/src/generated/prisma
|
||||||
|
|||||||
64
Dockerfile
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# FLUX SRL — Production Dockerfile (Multi-Stage)
|
||||||
|
# Next.js 16 + Prisma + next-intl + AI SDK
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
# ── Stage 1: Install dependencies ──
|
||||||
|
FROM node:22-alpine AS deps
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# ── Stage 2: Build the application ──
|
||||||
|
FROM node:22-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Prisma: generate client for linux-musl (Alpine)
|
||||||
|
# NOTE: dummy URL required because prisma.config.ts calls env("DATABASE_URL")
|
||||||
|
# during generate. The real URL is injected at runtime via docker-compose.
|
||||||
|
RUN DATABASE_URL="postgresql://dummy:dummy@localhost:5432/dummy" npx prisma generate
|
||||||
|
|
||||||
|
# Disable telemetry during build
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# ── Stage 3: Production runner ──
|
||||||
|
FROM node:22-alpine AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
|
||||||
|
# Security: run as non-root user
|
||||||
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
# Copy public assets (footage, images, GLB models)
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
|
||||||
|
# Copy standalone build
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
|
# Copy Prisma schema + generated client (needed for migrations at runtime)
|
||||||
|
COPY --from=builder /app/prisma ./prisma
|
||||||
|
COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma
|
||||||
|
COPY --from=builder /app/node_modules/@prisma ./node_modules/@prisma
|
||||||
|
|
||||||
|
# Copy i18n message files (required by next-intl at runtime)
|
||||||
|
COPY --from=builder /app/messages ./messages
|
||||||
|
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENV PORT=3000
|
||||||
|
ENV HOSTNAME="0.0.0.0"
|
||||||
|
|
||||||
|
CMD ["node", "server.js"]
|
||||||
36
README.md
@ -1,36 +0,0 @@
|
|||||||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
First, run the development server:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run dev
|
|
||||||
# or
|
|
||||||
yarn dev
|
|
||||||
# or
|
|
||||||
pnpm dev
|
|
||||||
# or
|
|
||||||
bun dev
|
|
||||||
```
|
|
||||||
|
|
||||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
|
||||||
|
|
||||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
|
||||||
|
|
||||||
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
|
||||||
|
|
||||||
## Learn More
|
|
||||||
|
|
||||||
To learn more about Next.js, take a look at the following resources:
|
|
||||||
|
|
||||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
|
||||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
|
||||||
|
|
||||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
|
||||||
|
|
||||||
## Deploy on Vercel
|
|
||||||
|
|
||||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
|
||||||
|
|
||||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
|
||||||
90
docker-compose.yml
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# FLUX SRL — Docker Compose (Production)
|
||||||
|
# Services: PostgreSQL 16 + Next.js App + Nginx
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
services:
|
||||||
|
|
||||||
|
# ── PostgreSQL Database ──
|
||||||
|
postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: ${DB_USER}
|
||||||
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||||
|
POSTGRES_DB: ${DB_NAME}
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- flux-net
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
command:
|
||||||
|
- postgres
|
||||||
|
- -c
|
||||||
|
- shared_buffers=256MB
|
||||||
|
- -c
|
||||||
|
- effective_cache_size=1GB
|
||||||
|
- -c
|
||||||
|
- work_mem=16MB
|
||||||
|
- -c
|
||||||
|
- maintenance_work_mem=128MB
|
||||||
|
- -c
|
||||||
|
- max_connections=50
|
||||||
|
- -c
|
||||||
|
- random_page_cost=1.1
|
||||||
|
|
||||||
|
# ── Next.js Application ──
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
restart: always
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
DATABASE_URL: postgresql://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}?schema=public
|
||||||
|
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||||
|
SESSION_SECRET: ${SESSION_SECRET}
|
||||||
|
NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL}
|
||||||
|
SMTP_HOST: ${SMTP_HOST}
|
||||||
|
SMTP_PORT: ${SMTP_PORT}
|
||||||
|
SMTP_USER: ${SMTP_USER}
|
||||||
|
SMTP_PASS: ${SMTP_PASS}
|
||||||
|
SMTP_FROM: ${SMTP_FROM}
|
||||||
|
SMTP_SECURE: ${SMTP_SECURE}
|
||||||
|
NODE_ENV: production
|
||||||
|
volumes:
|
||||||
|
- ./public/footage:/app/public/footage
|
||||||
|
networks:
|
||||||
|
- flux-net
|
||||||
|
expose:
|
||||||
|
- "3000"
|
||||||
|
|
||||||
|
# ── Nginx Reverse Proxy ──
|
||||||
|
nginx:
|
||||||
|
image: nginx:alpine
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||||
|
- ./nginx/conf.d:/etc/nginx/conf.d:ro
|
||||||
|
- ./certbot/conf:/etc/letsencrypt:ro
|
||||||
|
- ./certbot/www:/var/www/certbot:ro
|
||||||
|
depends_on:
|
||||||
|
- app
|
||||||
|
networks:
|
||||||
|
- flux-net
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
flux-net:
|
||||||
|
driver: bridge
|
||||||
22
env
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Conexión local a SQLite
|
||||||
|
#DATABASE_URL="file:./dev.db"
|
||||||
|
|
||||||
|
# POSTGRES SQL CONEXION
|
||||||
|
#:xDATABASE_URL="postgresql://flux_user:STRONG_PASSWORD@postgres:5432/flux_db?schema=public"
|
||||||
|
DATABASE_URL="postgresql://flux_user:dev_password@localhost:5432/flux_db?schema=public"
|
||||||
|
|
||||||
|
#FLUX SECRET Esto no se que hace
|
||||||
|
SESSION_SECRET="FLUX_SUPER_SECRET_KEY_2026_ARCHITECTURE"
|
||||||
|
|
||||||
|
# OPEN AI KEY
|
||||||
|
OPENAI_API_KEY=sk-proj-dsdsdsds-kaDAHhZXPYsK6-4uw0UWJZ0YuLnQfVoEA
|
||||||
|
|
||||||
|
NEXT_PUBLIC_APP_URL=http://localhost:3000 # En producción será https://www.rf-flux.com
|
||||||
|
|
||||||
|
#email Config
|
||||||
|
SMTP_HOST=smtp.gmail.com # (or smtp.office365.com, mail.fluxsrl.com, etc.)
|
||||||
|
SMTP_PORT=587 #(587 for TLS, 465 for SSL)
|
||||||
|
SMTP_USER=davidherran@dreamhousestudios.co
|
||||||
|
SMTP_PASS=syzybrtcidrkzehp #(Gmail: use App Password, not regular password)
|
||||||
|
SMTP_FROM=FLUX Operations <davidherran@dreamhousestudios.co>
|
||||||
|
SMTP_SECURE=false # (true for port 465, false for 587 with STARTTLS)
|
||||||
169
messages/de.json
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
{
|
||||||
|
"Navigation": {
|
||||||
|
"applications": "Anwendungen",
|
||||||
|
"globalMap": "Weltkarte",
|
||||||
|
"ourStory": "Unsere Geschichte",
|
||||||
|
"parts": "Ersatzteile",
|
||||||
|
"insideFlux": "Inside Flux"
|
||||||
|
},
|
||||||
|
"HeroReel": {
|
||||||
|
"title1": "Innovation,",
|
||||||
|
"title2": "nicht Imitation.",
|
||||||
|
"description1": "Innovationen vorantreiben, wo andere zögern",
|
||||||
|
"description2": "RF-Lösungen der nächsten Generation mit unübertroffener Präzision und europäischer Exzellenz."
|
||||||
|
},
|
||||||
|
"SpareParts": {
|
||||||
|
"title1": "Komponenten-",
|
||||||
|
"title2": "Matrix.",
|
||||||
|
"description": "Original FLUX Ersatzteile und Upgrades. Gewährleisten Sie maximale Leistung und Langlebigkeit für Ihre RF-Anlagen.",
|
||||||
|
"quoteBased": "Auf Anfrage"
|
||||||
|
},
|
||||||
|
"CartDrawer": {
|
||||||
|
"titleSupport": "Technischer Support",
|
||||||
|
"titleCart": "Warenkorb",
|
||||||
|
"tabParts": "Ersatzteile",
|
||||||
|
"tabDiagnostic": "Diagnose anfordern",
|
||||||
|
"emptyCart": "Ihr Warenkorb ist leer.",
|
||||||
|
"needHelp": "Benötigen Sie stattdessen technische Unterstützung?",
|
||||||
|
"quote": "Angebot",
|
||||||
|
"contactDetails": "Kontaktdaten",
|
||||||
|
"fullName": "Vollständiger Name",
|
||||||
|
"email": "Geschäftliche E-Mail",
|
||||||
|
"company": "Unternehmen",
|
||||||
|
"phone": "Telefon (Optional)",
|
||||||
|
"placeholderDiagnostic": "Beschreiben Sie die Fehlfunktion, Fehlercodes oder Symptome...",
|
||||||
|
"placeholderCart": "Zusätzliche Anmerkungen zu Ihrer Bestellung...",
|
||||||
|
"attachMedia": "Medien anhängen (Optional)",
|
||||||
|
"selectFiles": "Dateien auswählen",
|
||||||
|
"dragDrop": "Videos oder Fotos hierher ziehen. Max. 50MB pro Datei.",
|
||||||
|
"gdprAgreement": "Ich stimme der",
|
||||||
|
"dataPrivacy": "Datenschutzrichtlinie",
|
||||||
|
"gdprDesc": " zu. Meine Mediendateien werden von FLUX Engineering sicher analysiert und nach der Lösung gelöscht.",
|
||||||
|
"estSubtotal": "Geschätztes Subtotal",
|
||||||
|
"quotePending": "+ Positionen für Angebot ausstehend",
|
||||||
|
"btnSubmitEngineering": "An Engineering senden",
|
||||||
|
"btnRequestComponents": "Komponenten anfordern",
|
||||||
|
"encrypting": "Verschlüsselung der Medien...",
|
||||||
|
"connecting": "Verbindung wird hergestellt...",
|
||||||
|
"successTitle": "Anfrage erhalten",
|
||||||
|
"successDesc1": "Ihr Ticket",
|
||||||
|
"successDesc2": "wurde unserem Engineering-Team zugewiesen.",
|
||||||
|
"closePanel": "Panel schließen",
|
||||||
|
"modalTitle": "Datenschutz & Datenverarbeitung",
|
||||||
|
"modalDesc1": "In Übereinstimmung mit der EU-DSGVO erhebt FLUX Srl Ihre Kontaktinformationen und Mediendateien ausschließlich für technische Diagnosen und kommerzielle Angebote.",
|
||||||
|
"modalDesc2": "Automatische Löschung:",
|
||||||
|
"modalDesc3": "Alle von Ihnen angehängten Videos und Bilder werden in einer sicheren Quarantäneumgebung gespeichert und",
|
||||||
|
"modalDesc4": "dauerhaft von unseren Servern gelöscht,",
|
||||||
|
"modalDesc5": "sobald unsere Ingenieure Ihr Ticket gelöst haben.",
|
||||||
|
"understood": "Verstanden"
|
||||||
|
},
|
||||||
|
"HeritagePage": {
|
||||||
|
"backToOverview": "Zurück zur Übersicht",
|
||||||
|
"subtitle": "Das FLUX-Erbe",
|
||||||
|
"title1": "Ein Erbe gestalten.",
|
||||||
|
"title2": "Die Zukunft neu definieren.",
|
||||||
|
"emptyState": "Die ausführliche Geschichte wird derzeit im CMS verfasst."
|
||||||
|
},
|
||||||
|
"WhatWeDo": {
|
||||||
|
"subtitle": "Was wir tun",
|
||||||
|
"title": "Wir entwickeln fortschrittliche Hochfrequenztechnologien für die Industrien von morgen.",
|
||||||
|
"desc": "Innovation, Effizienz und Nachhaltigkeit in jeder Lösung.",
|
||||||
|
"tech": "Unsere Pulswellen-Technologie nutzt hochfrequente elektromagnetische Felder, um die Wassermoleküle in einem Produkt zu erhitzen.",
|
||||||
|
"process": "Wenn sie diesen Wellen ausgesetzt werden, vibrieren und rotieren die Moleküle Millionen Mal pro Sekunde.",
|
||||||
|
"efficiency": "Diese intrinsische und unmittelbare Wärmeübertragung erfolgt gleichmäßig, was den Prozess deutlich schneller und energieeffizienter macht als herkömmliche Methoden.",
|
||||||
|
"servicesSubtitle": "Unsere Dienstleistungen",
|
||||||
|
"servicesTitle1": "Optimierung Ihrer Fertigungsprozesse durch ",
|
||||||
|
"servicesTitle2": "Geschwindigkeit, Präzision ",
|
||||||
|
"servicesTitle3": "und ",
|
||||||
|
"servicesTitle4": "Energieoptimierung.",
|
||||||
|
"servicesDesc": "Dank der Vielseitigkeit unserer Technologie bieten wir maßgeschneiderte Lösungen für verschiedene Sektoren an und passen die RF-Innovation an die spezifischen Anforderungen jedes Bereichs an."
|
||||||
|
},
|
||||||
|
"AppsDeep": {
|
||||||
|
"subtitle": "Unsere Expertise",
|
||||||
|
"title1": "Industrielle ",
|
||||||
|
"title2": "Anwendungen.",
|
||||||
|
"moreInfo": "Mehr Informationen"
|
||||||
|
},
|
||||||
|
"GlobalOperations": {
|
||||||
|
"subtitle": "Weltweite Präsenz",
|
||||||
|
"title1": "Globale Reichweite.",
|
||||||
|
"title2": "Lokale Präzision.",
|
||||||
|
"filterAll": "Globales Netzwerk",
|
||||||
|
"filterInstallations": "Installationen",
|
||||||
|
"filterEvents": "Kommende Veranstaltungen",
|
||||||
|
"filterHQ": "Historischer Hauptsitz",
|
||||||
|
"filterByApp": "Nach Anwendung filtern:",
|
||||||
|
"networkStatus": "Netzwerkstatus",
|
||||||
|
"statusTracking": "Aktuelle Überwachung von {count} globalen Einsätzen, Live-Datenübertragung.",
|
||||||
|
"statusShowing": "Anzeige spezialisierter RF-{app}-Installationen in unserem globalen Netzwerk.",
|
||||||
|
"helpText": "[ Zum Drehen ziehen • Zum Zoomen scrollen ]",
|
||||||
|
"statusDetails": "Status / Details",
|
||||||
|
"viewCaseStudy": "Fallstudie ansehen",
|
||||||
|
"typeEvent": "Veranstaltung / Messe",
|
||||||
|
"typeHQ": "Hauptsitz",
|
||||||
|
"typeInstall": "Feldinstallation"
|
||||||
|
},
|
||||||
|
"AppsDashboard": {
|
||||||
|
"subtitle": "RF-Anwendungen",
|
||||||
|
"title1": "Entwickelt für Ihre Branche.",
|
||||||
|
"title2": "Optimiert für Effizienz.",
|
||||||
|
"desc": "Unsere Solid-State-RF-Technologie ist hochflexibel für die Produktionsplanung. Wählen Sie unten eine Anwendung aus, um die Auswirkungen auf Ihre Betriebskennzahlen zu sehen.",
|
||||||
|
"calcROI": "ROI berechnen",
|
||||||
|
"compareTech": "Technik vergleichen",
|
||||||
|
"viewSpecs": "Vollständige Spezifikationen"
|
||||||
|
},
|
||||||
|
"OurStory": {
|
||||||
|
"subtitle": "Unternehmenserbe",
|
||||||
|
"title": "Eine Geschichte der Innovation."
|
||||||
|
},
|
||||||
|
"NewsHub": {
|
||||||
|
"subtitle": "Inside Flux",
|
||||||
|
"title1": "Geschichten aus dem ",
|
||||||
|
"title2": "Kern.",
|
||||||
|
"description": "Tech-Updates, bahnbrechende Entwicklungen und ein Blick hinter die Kulissen auf die Menschen, die die Zukunft der RF-Technologie gestalten.",
|
||||||
|
"emptyState": "Die Redaktion bereitet derzeit die erste Geschichte vor.",
|
||||||
|
"readFull": "Ganze Geschichte lesen",
|
||||||
|
"readMore": "Mehr lesen"
|
||||||
|
},
|
||||||
|
"PatrizioLegacy": {
|
||||||
|
"subtitle": "Unser Erbe",
|
||||||
|
"title1": "40 Jahre RF-Exzellenz.",
|
||||||
|
"title2": "Neu gedacht für 2026.",
|
||||||
|
"p1_1": "Gegründet und geführt von Ingenieur ",
|
||||||
|
"p1_2": "Patrizio Grando",
|
||||||
|
"p1_3": ", der 2023 wieder in das Geschäft eintrat, um sein Erbe der Innovation fortzusetzen. FLUX Srl führt vier Jahrzehnte beispielloser Expertise in der Hochfrequenztechnologie fort.",
|
||||||
|
"p2": "Wir konzentrieren uns auf die Entwicklung modernster Solid-State-RF-Lösungen für innovative Märkte, in denen Wettbewerber nicht über die erforderliche Erfahrung und das detaillierte technische Fachwissen verfügen.",
|
||||||
|
"button": "Lesen Sie den Deep Dive in Patrizios Erbe"
|
||||||
|
},
|
||||||
|
"CaseStudyModal": {
|
||||||
|
"typeEvent": "Veranstaltung / Messe",
|
||||||
|
"typeHQ": "Hauptsitz",
|
||||||
|
"typeInstall": "Feldinstallation",
|
||||||
|
"keyHighlight": "Haupthighlight",
|
||||||
|
"keyMetric": "Kennzahl",
|
||||||
|
"locationStand": "Standort / Stand",
|
||||||
|
"energyImpact": "Energieauswirkung",
|
||||||
|
"systemStatus": "Systemstatus",
|
||||||
|
"scheduled": "Geplant",
|
||||||
|
"concluded": "Abgeschlossen",
|
||||||
|
"operational": "Voll einsatzbereit",
|
||||||
|
"eventOverview": "Veranstaltungsübersicht",
|
||||||
|
"projectChronicle": "Projektchronik",
|
||||||
|
"pendingData": "[ Chronikdaten für diesen Knoten ausstehend ]",
|
||||||
|
"mediaGallery": "Mediengalerie"
|
||||||
|
},
|
||||||
|
"Footer": {
|
||||||
|
"madeInItaly": "Hergestellt in Italien",
|
||||||
|
"rights": "Alle Rechte vorbehalten",
|
||||||
|
"techTitle": "Technologie",
|
||||||
|
"appsTitle": "Anwendungen",
|
||||||
|
"companyTitle": "Unternehmen",
|
||||||
|
"hqTitle": "Hauptsitz",
|
||||||
|
"techSolidState": "Solid-State RF",
|
||||||
|
"techMicrowave": "Mikrowellensysteme",
|
||||||
|
"techEfficiency": "Energieeffizienz",
|
||||||
|
"companyStory": "Unsere Geschichte",
|
||||||
|
"companyMap": "Globales Netzwerk",
|
||||||
|
"companyNews": "Inside Flux"
|
||||||
|
}
|
||||||
|
}
|
||||||
169
messages/en.json
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
{
|
||||||
|
"Navigation": {
|
||||||
|
"applications": "Applications",
|
||||||
|
"globalMap": "Global Map",
|
||||||
|
"ourStory": "Our Story",
|
||||||
|
"parts": "Spare Parts",
|
||||||
|
"insideFlux": "Inside Flux"
|
||||||
|
},
|
||||||
|
"HeroReel": {
|
||||||
|
"title1": "Innovation,",
|
||||||
|
"title2": "not imitation.",
|
||||||
|
"description1": "Driving innovation where others hesitate",
|
||||||
|
"description2": "Crafting Next-Gen RF Solutions With Unmatched Precision and European Excellence."
|
||||||
|
},
|
||||||
|
"SpareParts": {
|
||||||
|
"title1": "Component",
|
||||||
|
"title2": "Matrix.",
|
||||||
|
"description": "Original FLUX replacement parts and upgrades. Ensure maximum performance and longevity for your RF equipment.",
|
||||||
|
"quoteBased": "Quote Based"
|
||||||
|
},
|
||||||
|
"CartDrawer": {
|
||||||
|
"titleSupport": "Tech Support",
|
||||||
|
"titleCart": "Operations Cart",
|
||||||
|
"tabParts": "Spare Parts",
|
||||||
|
"tabDiagnostic": "Request Diagnostic",
|
||||||
|
"emptyCart": "Your cart is empty.",
|
||||||
|
"needHelp": "Need technical assistance instead?",
|
||||||
|
"quote": "Quote",
|
||||||
|
"contactDetails": "Contact Details",
|
||||||
|
"fullName": "Full Name",
|
||||||
|
"email": "Work Email",
|
||||||
|
"company": "Company",
|
||||||
|
"phone": "Phone (Optional)",
|
||||||
|
"placeholderDiagnostic": "Describe the malfunction, error codes, or symptoms...",
|
||||||
|
"placeholderCart": "Additional notes for your order...",
|
||||||
|
"attachMedia": "Attach Media (Optional)",
|
||||||
|
"selectFiles": "Select Files",
|
||||||
|
"dragDrop": "Drag videos or photos here. Max 50MB per file.",
|
||||||
|
"gdprAgreement": "I agree to the",
|
||||||
|
"dataPrivacy": "Data Privacy Policy",
|
||||||
|
"gdprDesc": ". My media files will be securely analyzed by FLUX Engineering and purged upon resolution.",
|
||||||
|
"estSubtotal": "Est. Subtotal",
|
||||||
|
"quotePending": "+ Quote items pending",
|
||||||
|
"btnSubmitEngineering": "Submit to Engineering",
|
||||||
|
"btnRequestComponents": "Request Components",
|
||||||
|
"encrypting": "Encrypting Media...",
|
||||||
|
"connecting": "Connecting...",
|
||||||
|
"successTitle": "Request Received",
|
||||||
|
"successDesc1": "Your ticket",
|
||||||
|
"successDesc2": "has been assigned to our engineering team.",
|
||||||
|
"closePanel": "Close Panel",
|
||||||
|
"modalTitle": "Privacy & Data Handling",
|
||||||
|
"modalDesc1": "In compliance with EU GDPR, FLUX Srl collects your contact information and media files strictly for technical diagnostics and commercial quoting.",
|
||||||
|
"modalDesc2": "Automated Purge:",
|
||||||
|
"modalDesc3": "All videos and images you attach are stored in a secure quarantine environment and will be",
|
||||||
|
"modalDesc4": "permanently deleted from our servers",
|
||||||
|
"modalDesc5": "automatically once our engineers resolve your ticket.",
|
||||||
|
"understood": "Understood"
|
||||||
|
},
|
||||||
|
"HeritagePage": {
|
||||||
|
"backToOverview": "Back to Overview",
|
||||||
|
"subtitle": "The FLUX Heritage",
|
||||||
|
"title1": "Engineering a legacy.",
|
||||||
|
"title2": "Redefining the future.",
|
||||||
|
"emptyState": "The deep story is currently being written in the CMS."
|
||||||
|
},
|
||||||
|
"WhatWeDo": {
|
||||||
|
"subtitle": "What We Do",
|
||||||
|
"title": "We develop advanced radio frequency technologies to drive the industries of tomorrow.",
|
||||||
|
"desc": "Delivering innovation, efficiency, and sustainability in every solution.",
|
||||||
|
"tech": "Our pulsed waves technology uses high-frequency electromagnetic fields to heat the water molecules within a product.",
|
||||||
|
"process": "When exposed to these waves, the molecules vibrate and rotate millions of times per second.",
|
||||||
|
"efficiency": "This intrinsic and immediate heat transfer occurs uniformly, making the process significantly faster and more energy-efficient than conventional methods.",
|
||||||
|
"servicesSubtitle": "Our Services",
|
||||||
|
"servicesTitle1": "Elevating your manufacturing processes with ",
|
||||||
|
"servicesTitle2": "speed, precision, ",
|
||||||
|
"servicesTitle3": "and ",
|
||||||
|
"servicesTitle4": "energy optimization.",
|
||||||
|
"servicesDesc": "Thanks to the versatility of our technology, we offer dedicated solutions across multiple sectors, adapting RF innovation to the specific demands of each field."
|
||||||
|
},
|
||||||
|
"AppsDeep": {
|
||||||
|
"subtitle": "Our Expertise",
|
||||||
|
"title1": "Industrial ",
|
||||||
|
"title2": "Applications.",
|
||||||
|
"moreInfo": "More Information"
|
||||||
|
},
|
||||||
|
"GlobalOperations": {
|
||||||
|
"subtitle": "Worldwide Presence",
|
||||||
|
"title1": "Global scale.",
|
||||||
|
"title2": "Local precision.",
|
||||||
|
"filterAll": "Global Network",
|
||||||
|
"filterInstallations": "Installations",
|
||||||
|
"filterEvents": "Upcoming Events",
|
||||||
|
"filterHQ": "Legacy HQ",
|
||||||
|
"filterByApp": "Filter by Application:",
|
||||||
|
"networkStatus": "Network Status",
|
||||||
|
"statusTracking": "Currently tracking {count} deployments globally, broadcasting live data.",
|
||||||
|
"statusShowing": "Showing specialized RF {app} installations across our global network.",
|
||||||
|
"helpText": "[ Drag to rotate • Scroll to zoom ]",
|
||||||
|
"statusDetails": "Status / Details",
|
||||||
|
"viewCaseStudy": "View Case Study",
|
||||||
|
"typeEvent": "Event / Exhibition",
|
||||||
|
"typeHQ": "Headquarters",
|
||||||
|
"typeInstall": "Field Installation"
|
||||||
|
},
|
||||||
|
"AppsDashboard": {
|
||||||
|
"subtitle": "RF Applications",
|
||||||
|
"title1": "Engineered for your industry.",
|
||||||
|
"title2": "Optimized for efficiency.",
|
||||||
|
"desc": "Our solid-state RF technology is highly flexible for production scheduling. Select an application below to see the impact on your operational metrics.",
|
||||||
|
"calcROI": "Calculate ROI",
|
||||||
|
"compareTech": "Compare Tech",
|
||||||
|
"viewSpecs": "View Full Specs"
|
||||||
|
},
|
||||||
|
"OurStory": {
|
||||||
|
"subtitle": "Company Legacy",
|
||||||
|
"title": "A history of innovation."
|
||||||
|
},
|
||||||
|
"NewsHub": {
|
||||||
|
"subtitle": "Inside Flux",
|
||||||
|
"title1": "Stories from the ",
|
||||||
|
"title2": "core.",
|
||||||
|
"description": "Tech updates, engineering breakthroughs, and a behind-the-scenes look at the people powering the future of RF technology.",
|
||||||
|
"emptyState": "The newsroom is currently preparing the first story.",
|
||||||
|
"readFull": "Read the full story",
|
||||||
|
"readMore": "Read more"
|
||||||
|
},
|
||||||
|
"PatrizioLegacy": {
|
||||||
|
"subtitle": "Our Heritage",
|
||||||
|
"title1": "40 Years of RF Excellence.",
|
||||||
|
"title2": "Reimagined for 2026.",
|
||||||
|
"p1_1": "Founded and led by Engineer ",
|
||||||
|
"p1_2": "Patrizio Grando",
|
||||||
|
"p1_3": ", who re-entered the business in 2023 to continue his legacy of innovation. FLUX Srl carries forward four decades of unparalleled expertise in Radio Frequency technology.",
|
||||||
|
"p2": "We focus on developing state-of-the-art solid-state RF solutions for innovative markets, where competitors lack the necessary experience and detailed engineering expertise.",
|
||||||
|
"button": "Read the deep dive into Patrizio's Legacy"
|
||||||
|
},
|
||||||
|
"CaseStudyModal": {
|
||||||
|
"typeEvent": "Event / Exhibition",
|
||||||
|
"typeHQ": "Headquarters",
|
||||||
|
"typeInstall": "Field Installation",
|
||||||
|
"keyHighlight": "Key Highlight",
|
||||||
|
"keyMetric": "Key Metric",
|
||||||
|
"locationStand": "Location / Stand",
|
||||||
|
"energyImpact": "Energy Impact",
|
||||||
|
"systemStatus": "System Status",
|
||||||
|
"scheduled": "Scheduled",
|
||||||
|
"concluded": "Concluded",
|
||||||
|
"operational": "Fully Operational",
|
||||||
|
"eventOverview": "Event Overview",
|
||||||
|
"projectChronicle": "Project Chronicle",
|
||||||
|
"pendingData": "[ Chronicle data pending for this node ]",
|
||||||
|
"mediaGallery": "Media Gallery"
|
||||||
|
},
|
||||||
|
"Footer": {
|
||||||
|
"madeInItaly": "Made in Italy",
|
||||||
|
"rights": "All rights reserved",
|
||||||
|
"techTitle": "Technology",
|
||||||
|
"appsTitle": "Applications",
|
||||||
|
"companyTitle": "Company",
|
||||||
|
"hqTitle": "Headquarters",
|
||||||
|
"techSolidState": "Solid-State RF",
|
||||||
|
"techMicrowave": "Microwave Systems",
|
||||||
|
"techEfficiency": "Energy Efficiency",
|
||||||
|
"companyStory": "Our Story",
|
||||||
|
"companyMap": "Global Network",
|
||||||
|
"companyNews": "Inside Flux"
|
||||||
|
}
|
||||||
|
}
|
||||||
169
messages/es.json
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
{
|
||||||
|
"Navigation": {
|
||||||
|
"applications": "Aplicaciones",
|
||||||
|
"globalMap": "Mapa Global",
|
||||||
|
"ourStory": "Nuestra Historia",
|
||||||
|
"parts": "Repuestos",
|
||||||
|
"insideFlux": "Inside Flux"
|
||||||
|
},
|
||||||
|
"HeroReel": {
|
||||||
|
"title1": "Innovación,",
|
||||||
|
"title2": "no imitación.",
|
||||||
|
"description1": "Impulsando la innovación donde otros dudan",
|
||||||
|
"description2": "Creando soluciones de RF de última generación con precisión inigualable y excelencia europea."
|
||||||
|
},
|
||||||
|
"SpareParts": {
|
||||||
|
"title1": "Matriz de",
|
||||||
|
"title2": "Componentes.",
|
||||||
|
"description": "Repuestos y actualizaciones originales de FLUX. Asegure el máximo rendimiento y longevidad para su equipo de RF.",
|
||||||
|
"quoteBased": "Bajo Cotización"
|
||||||
|
},
|
||||||
|
"CartDrawer": {
|
||||||
|
"titleSupport": "Soporte Técnico",
|
||||||
|
"titleCart": "Carrito de Operaciones",
|
||||||
|
"tabParts": "Repuestos",
|
||||||
|
"tabDiagnostic": "Solicitar Diagnóstico",
|
||||||
|
"emptyCart": "Tu carrito está vacío.",
|
||||||
|
"needHelp": "¿Necesitas asistencia técnica en su lugar?",
|
||||||
|
"quote": "Cotización",
|
||||||
|
"contactDetails": "Detalles de Contacto",
|
||||||
|
"fullName": "Nombre Completo",
|
||||||
|
"email": "Correo Corporativo",
|
||||||
|
"company": "Empresa",
|
||||||
|
"phone": "Teléfono (Opcional)",
|
||||||
|
"placeholderDiagnostic": "Describe la falla, códigos de error o síntomas...",
|
||||||
|
"placeholderCart": "Notas adicionales para tu pedido...",
|
||||||
|
"attachMedia": "Adjuntar Archivos (Opcional)",
|
||||||
|
"selectFiles": "Seleccionar Archivos",
|
||||||
|
"dragDrop": "Arrastra videos o fotos aquí. Máximo 50MB por archivo.",
|
||||||
|
"gdprAgreement": "Acepto la",
|
||||||
|
"dataPrivacy": "Política de Privacidad de Datos",
|
||||||
|
"gdprDesc": ". Mis archivos serán analizados de forma segura por FLUX Engineering y eliminados tras la resolución.",
|
||||||
|
"estSubtotal": "Subtotal Est.",
|
||||||
|
"quotePending": "+ Artículos pendientes de cotización",
|
||||||
|
"btnSubmitEngineering": "Enviar a Ingeniería",
|
||||||
|
"btnRequestComponents": "Solicitar Componentes",
|
||||||
|
"encrypting": "Encriptando Archivos...",
|
||||||
|
"connecting": "Conectando...",
|
||||||
|
"successTitle": "Solicitud Recibida",
|
||||||
|
"successDesc1": "Tu ticket",
|
||||||
|
"successDesc2": "ha sido asignado a nuestro equipo de ingeniería.",
|
||||||
|
"closePanel": "Cerrar Panel",
|
||||||
|
"modalTitle": "Privacidad y Manejo de Datos",
|
||||||
|
"modalDesc1": "En cumplimiento con el RGPD de la UE, FLUX Srl recopila tu información de contacto y archivos estrictamente para diagnóstico técnico y cotizaciones comerciales.",
|
||||||
|
"modalDesc2": "Eliminación Automática:",
|
||||||
|
"modalDesc3": "Todos los videos e imágenes adjuntos se almacenan en un entorno seguro y serán",
|
||||||
|
"modalDesc4": "borrados permanentemente de nuestros servidores",
|
||||||
|
"modalDesc5": "automáticamente una vez que nuestros ingenieros resuelvan tu ticket.",
|
||||||
|
"understood": "Entendido"
|
||||||
|
},
|
||||||
|
"HeritagePage": {
|
||||||
|
"backToOverview": "Volver a la Vista General",
|
||||||
|
"subtitle": "El Legado de FLUX",
|
||||||
|
"title1": "Ingeniando un legado.",
|
||||||
|
"title2": "Redefiniendo el futuro.",
|
||||||
|
"emptyState": "La historia profunda se está redactando actualmente en el CMS."
|
||||||
|
},
|
||||||
|
"WhatWeDo": {
|
||||||
|
"subtitle": "Qué Hacemos",
|
||||||
|
"title": "Desarrollamos tecnologías avanzadas de radiofrecuencia para impulsar las industrias del mañana.",
|
||||||
|
"desc": "Entregando innovación, eficiencia y sostenibilidad en cada solución.",
|
||||||
|
"tech": "Nuestra tecnología de ondas pulsadas utiliza campos electromagnéticos de alta frecuencia para calentar las moléculas de agua dentro de un producto.",
|
||||||
|
"process": "Al exponerse a estas ondas, las moléculas vibran y giran millones de veces por segundo.",
|
||||||
|
"efficiency": "Esta transferencia de calor intrínseca e inmediata ocurre de manera uniforme, haciendo que el proceso sea significativamente más rápido y eficiente energéticamente que los métodos convencionales.",
|
||||||
|
"servicesSubtitle": "Nuestros Servicios",
|
||||||
|
"servicesTitle1": "Elevando sus procesos de fabricación con ",
|
||||||
|
"servicesTitle2": "velocidad, precisión, ",
|
||||||
|
"servicesTitle3": "y ",
|
||||||
|
"servicesTitle4": "optimización energética.",
|
||||||
|
"servicesDesc": "Gracias a la versatilidad de nuestra tecnología, ofrecemos soluciones dedicadas en múltiples sectores, adaptando la innovación de RF a las demandas específicas de cada campo."
|
||||||
|
},
|
||||||
|
"AppsDeep": {
|
||||||
|
"subtitle": "Nuestra Experiencia",
|
||||||
|
"title1": "Aplicaciones ",
|
||||||
|
"title2": "Industriales.",
|
||||||
|
"moreInfo": "Más Información"
|
||||||
|
},
|
||||||
|
"GlobalOperations": {
|
||||||
|
"subtitle": "Presencia Mundial",
|
||||||
|
"title1": "Escala global.",
|
||||||
|
"title2": "Precisión local.",
|
||||||
|
"filterAll": "Red Global",
|
||||||
|
"filterInstallations": "Instalaciones",
|
||||||
|
"filterEvents": "Próximos Eventos",
|
||||||
|
"filterHQ": "Sede Histórica",
|
||||||
|
"filterByApp": "Filtrar por aplicación:",
|
||||||
|
"networkStatus": "Estado de la Red",
|
||||||
|
"statusTracking": "Monitoreando actualmente {count} despliegues globales, transmitiendo datos en vivo.",
|
||||||
|
"statusShowing": "Mostrando instalaciones especializadas de RF en {app} a través de nuestra red global.",
|
||||||
|
"helpText": "[ Arrastre para rotar • Desplazar para zoom ]",
|
||||||
|
"statusDetails": "Estado / Detalles",
|
||||||
|
"viewCaseStudy": "Ver Caso de Estudio",
|
||||||
|
"typeEvent": "Evento / Exhibición",
|
||||||
|
"typeHQ": "Sede Central",
|
||||||
|
"typeInstall": "Instalación de Campo"
|
||||||
|
},
|
||||||
|
"AppsDashboard": {
|
||||||
|
"subtitle": "Aplicaciones de RF",
|
||||||
|
"title1": "Diseñado para su industria.",
|
||||||
|
"title2": "Optimizado para la eficiencia.",
|
||||||
|
"desc": "Nuestra tecnología de RF de estado sólido es altamente flexible para la programación de producción. Seleccione una aplicación a continuación para ver el impacto en sus métricas operativas.",
|
||||||
|
"calcROI": "Calcular ROI",
|
||||||
|
"compareTech": "Comparar Tecnologías",
|
||||||
|
"viewSpecs": "Ver Especificaciones"
|
||||||
|
},
|
||||||
|
"OurStory": {
|
||||||
|
"subtitle": "Legado de la Empresa",
|
||||||
|
"title": "Una historia de innovación."
|
||||||
|
},
|
||||||
|
"NewsHub": {
|
||||||
|
"subtitle": "Inside Flux",
|
||||||
|
"title1": "Historias desde el ",
|
||||||
|
"title2": "núcleo.",
|
||||||
|
"description": "Actualizaciones tecnológicas, avances de ingeniería y una mirada detrás de escena a las personas que impulsan el futuro de la tecnología RF.",
|
||||||
|
"emptyState": "La sala de redacción está preparando la primera historia.",
|
||||||
|
"readFull": "Leer historia completa",
|
||||||
|
"readMore": "Leer más"
|
||||||
|
},
|
||||||
|
"PatrizioLegacy": {
|
||||||
|
"subtitle": "Nuestra Herencia",
|
||||||
|
"title1": "40 Años de Excelencia en RF.",
|
||||||
|
"title2": "Reimaginado para 2026.",
|
||||||
|
"p1_1": "Fundada y dirigida por el Ingeniero ",
|
||||||
|
"p1_2": "Patrizio Grando",
|
||||||
|
"p1_3": ", quien se reintegró a la empresa en 2023 para continuar su legado de innovación. FLUX Srl lleva adelante cuatro décadas de experiencia inigualable en tecnología de Radiofrecuencia.",
|
||||||
|
"p2": "Nos enfocamos en desarrollar soluciones de RF de estado sólido de vanguardia para mercados innovadores, donde los competidores carecen de la experiencia necesaria y el conocimiento detallado de ingeniería.",
|
||||||
|
"button": "Leer más sobre el legado de Patrizio"
|
||||||
|
},
|
||||||
|
"CaseStudyModal": {
|
||||||
|
"typeEvent": "Evento / Exhibición",
|
||||||
|
"typeHQ": "Sede Central",
|
||||||
|
"typeInstall": "Instalación de Campo",
|
||||||
|
"keyHighlight": "Hito Clave",
|
||||||
|
"keyMetric": "Métrica Clave",
|
||||||
|
"locationStand": "Ubicación / Stand",
|
||||||
|
"energyImpact": "Impacto Energético",
|
||||||
|
"systemStatus": "Estado del Sistema",
|
||||||
|
"scheduled": "Programado",
|
||||||
|
"concluded": "Concluido",
|
||||||
|
"operational": "Totalmente Operativo",
|
||||||
|
"eventOverview": "Resumen del Evento",
|
||||||
|
"projectChronicle": "Crónica del Proyecto",
|
||||||
|
"pendingData": "[ Datos de crónica pendientes para este nodo ]",
|
||||||
|
"mediaGallery": "Galería de Medios"
|
||||||
|
},
|
||||||
|
"Footer": {
|
||||||
|
"madeInItaly": "Hecho en Italia",
|
||||||
|
"rights": "Todos los derechos reservados",
|
||||||
|
"techTitle": "Tecnología",
|
||||||
|
"appsTitle": "Aplicaciones",
|
||||||
|
"companyTitle": "Empresa",
|
||||||
|
"hqTitle": "Sede Central",
|
||||||
|
"techSolidState": "RF de Estado Sólido",
|
||||||
|
"techMicrowave": "Sistemas de Microondas",
|
||||||
|
"techEfficiency": "Eficiencia Energética",
|
||||||
|
"companyStory": "Nuestra Historia",
|
||||||
|
"companyMap": "Red Global",
|
||||||
|
"companyNews": "Inside Flux"
|
||||||
|
}
|
||||||
|
}
|
||||||
169
messages/it.json
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
{
|
||||||
|
"Navigation": {
|
||||||
|
"applications": "Applicazioni",
|
||||||
|
"globalMap": "Mappa Globale",
|
||||||
|
"ourStory": "La nostra Storia",
|
||||||
|
"parts": "Ricambi",
|
||||||
|
"insideFlux": "Inside Flux"
|
||||||
|
},
|
||||||
|
"HeroReel": {
|
||||||
|
"title1": "Innovazione,",
|
||||||
|
"title2": "non imitazione.",
|
||||||
|
"description1": "Guidare l'innovazione dove altri esitano",
|
||||||
|
"description2": "Creare soluzioni RF di prossima generazione con precisione impareggiabile ed eccellenza europea."
|
||||||
|
},
|
||||||
|
"SpareParts": {
|
||||||
|
"title1": "Matrice",
|
||||||
|
"title2": "Componenti.",
|
||||||
|
"description": "Ricambi e aggiornamenti originali FLUX. Garantite la massima resa e longevità alle vostre apparecchiature RF.",
|
||||||
|
"quoteBased": "Su Preventivo"
|
||||||
|
},
|
||||||
|
"CartDrawer": {
|
||||||
|
"titleSupport": "Supporto Tecnico",
|
||||||
|
"titleCart": "Carrello Operazioni",
|
||||||
|
"tabParts": "Ricambi",
|
||||||
|
"tabDiagnostic": "Richiedi Diagnostica",
|
||||||
|
"emptyCart": "Il tuo carrello è vuoto.",
|
||||||
|
"needHelp": "Hai bisogno invece di assistenza tecnica?",
|
||||||
|
"quote": "Preventivo",
|
||||||
|
"contactDetails": "Dettagli di Contatto",
|
||||||
|
"fullName": "Nome Completo",
|
||||||
|
"email": "Email Aziendale",
|
||||||
|
"company": "Azienda",
|
||||||
|
"phone": "Telefono (Opzionale)",
|
||||||
|
"placeholderDiagnostic": "Descrivi il malfunzionamento, codici errore o sintomi...",
|
||||||
|
"placeholderCart": "Note aggiuntive per il tuo ordine...",
|
||||||
|
"attachMedia": "Allega File (Opzionale)",
|
||||||
|
"selectFiles": "Seleziona File",
|
||||||
|
"dragDrop": "Trascina video o foto qui. Max 50MB per file.",
|
||||||
|
"gdprAgreement": "Accetto la",
|
||||||
|
"dataPrivacy": "Informativa sulla Privacy",
|
||||||
|
"gdprDesc": ". I miei file multimediali saranno analizzati in sicurezza da FLUX Engineering e cancellati alla risoluzione.",
|
||||||
|
"estSubtotal": "Subtotale Stimato",
|
||||||
|
"quotePending": "+ Articoli in attesa di preventivo",
|
||||||
|
"btnSubmitEngineering": "Invia a Ingegneria",
|
||||||
|
"btnRequestComponents": "Richiedi Componenti",
|
||||||
|
"encrypting": "Crittografia File...",
|
||||||
|
"connecting": "Connessione in corso...",
|
||||||
|
"successTitle": "Richiesta Ricevuta",
|
||||||
|
"successDesc1": "Il tuo ticket",
|
||||||
|
"successDesc2": "è stato assegnato al nostro team di ingegneria.",
|
||||||
|
"closePanel": "Chiudi Pannello",
|
||||||
|
"modalTitle": "Privacy e Gestione Dati",
|
||||||
|
"modalDesc1": "In conformità con il GDPR UE, FLUX Srl raccoglie i tuoi dati di contatto e i file multimediali esclusivamente per diagnostica tecnica e preventivi commerciali.",
|
||||||
|
"modalDesc2": "Cancellazione Automatica:",
|
||||||
|
"modalDesc3": "Tutti i video e le immagini allegati sono archiviati in un ambiente di quarantena sicuro e saranno",
|
||||||
|
"modalDesc4": "eliminati permanentemente dai nostri server",
|
||||||
|
"modalDesc5": "automaticamente una volta che i nostri ingegneri avranno risolto il tuo ticket.",
|
||||||
|
"understood": "Capito"
|
||||||
|
},
|
||||||
|
"HeritagePage": {
|
||||||
|
"backToOverview": "Torna alla Panoramica",
|
||||||
|
"subtitle": "L'Eredità FLUX",
|
||||||
|
"title1": "Progettare un'eredità.",
|
||||||
|
"title2": "Ridefinire il futuro.",
|
||||||
|
"emptyState": "La storia approfondita è attualmente in fase di redazione nel CMS."
|
||||||
|
},
|
||||||
|
"WhatWeDo": {
|
||||||
|
"subtitle": "Cosa Facciamo",
|
||||||
|
"title": "Sviluppiamo tecnologie avanzate a radiofrequenza per guidare le industrie di domani.",
|
||||||
|
"desc": "Innovazione, efficienza e sostenibilità in ogni soluzione.",
|
||||||
|
"tech": "La nostra tecnologia a onde pulsate utilizza campi elettromagnetici ad alta frequenza per riscaldare le molecole d'acqua all'interno di un prodotto.",
|
||||||
|
"process": "Quando esposte a queste onde, le molecole vibrano e ruotano milioni di volte al secondo.",
|
||||||
|
"efficiency": "Questo trasferimento di calore intrinseco e immediato avviene in modo uniforme, rendendo il processo significativamente più veloce ed efficiente dal punto di vista energetico rispetto ai metodi convenzionali.",
|
||||||
|
"servicesSubtitle": "I Nostri Servizi",
|
||||||
|
"servicesTitle1": "Eleviamo i vostri processi produttivi con ",
|
||||||
|
"servicesTitle2": "velocità, precisione ",
|
||||||
|
"servicesTitle3": "e ",
|
||||||
|
"servicesTitle4": "ottimizzazione energetica.",
|
||||||
|
"servicesDesc": "Grazie alla versatilità della nostra tecnologia, offriamo soluzioni dedicate in molteplici settori, adattando l'innovazione RF alle richieste specifiche di ogni campo."
|
||||||
|
},
|
||||||
|
"AppsDeep": {
|
||||||
|
"subtitle": "La Nostra Esperienza",
|
||||||
|
"title1": "Applicazioni ",
|
||||||
|
"title2": "Industriali.",
|
||||||
|
"moreInfo": "Maggiori Informazioni"
|
||||||
|
},
|
||||||
|
"GlobalOperations": {
|
||||||
|
"subtitle": "Presenza Globale",
|
||||||
|
"title1": "Scala globale.",
|
||||||
|
"title2": "Precisione locale.",
|
||||||
|
"filterAll": "Rete Globale",
|
||||||
|
"filterInstallations": "Installazioni",
|
||||||
|
"filterEvents": "Prossimi Eventi",
|
||||||
|
"filterHQ": "Sede Storica",
|
||||||
|
"filterByApp": "Filtra per applicazione:",
|
||||||
|
"networkStatus": "Stato della Rete",
|
||||||
|
"statusTracking": "Attualmente monitoriamo {count} installazioni globali, trasmettendo dati in tempo reale.",
|
||||||
|
"statusShowing": "Mostrando installazioni RF specializzate in {app} attraverso la nostra rete globale.",
|
||||||
|
"helpText": "[ Trascina per ruotare • Scorri per lo zoom ]",
|
||||||
|
"statusDetails": "Stato / Dettagli",
|
||||||
|
"viewCaseStudy": "Vedi Caso di Studio",
|
||||||
|
"typeEvent": "Evento / Esposizione",
|
||||||
|
"typeHQ": "Sede Centrale",
|
||||||
|
"typeInstall": "Installazione sul Campo"
|
||||||
|
},
|
||||||
|
"AppsDashboard": {
|
||||||
|
"subtitle": "Applicazioni RF",
|
||||||
|
"title1": "Progettato per la tua industria.",
|
||||||
|
"title2": "Ottimizzato per l'efficienza.",
|
||||||
|
"desc": "La nostra tecnologia RF a stato solido è altamente flessibile per la programmazione della produzione. Seleziona un'applicazione qui sotto per vedere l'impatto sulle tue metriche operative.",
|
||||||
|
"calcROI": "Calcola ROI",
|
||||||
|
"compareTech": "Confronta Tecnologie",
|
||||||
|
"viewSpecs": "Specifiche Complete"
|
||||||
|
},
|
||||||
|
"OurStory": {
|
||||||
|
"subtitle": "Eredità Aziendale",
|
||||||
|
"title": "Una storia di innovazione."
|
||||||
|
},
|
||||||
|
"NewsHub": {
|
||||||
|
"subtitle": "Dentro Flux",
|
||||||
|
"title1": "Storie dal ",
|
||||||
|
"title2": "cuore.",
|
||||||
|
"description": "Aggiornamenti tecnologici, scoperte ingegneristiche e uno sguardo dietro le quinte alle persone che alimentano il futuro della tecnologia RF.",
|
||||||
|
"emptyState": "La redazione sta preparando la prima storia.",
|
||||||
|
"readFull": "Leggi la storia completa",
|
||||||
|
"readMore": "Leggi di più"
|
||||||
|
},
|
||||||
|
"PatrizioLegacy": {
|
||||||
|
"subtitle": "La Nostra Eredità",
|
||||||
|
"title1": "40 Anni di Eccellenza RF.",
|
||||||
|
"title2": "Reimmaginata per il 2026.",
|
||||||
|
"p1_1": "Fondata e guidata dall'Ingegnere ",
|
||||||
|
"p1_2": "Patrizio Grando",
|
||||||
|
"p1_3": ", rientrato nel business nel 2023 per continuare il suo percorso di innovazione. FLUX Srl porta avanti quattro decenni di competenza senza pari nella tecnologia a Radiofrequenza.",
|
||||||
|
"p2": "Ci concentriamo sullo sviluppo di soluzioni RF allo stato solido all'avanguardia per mercati innovativi, dove i competitor mancano dell'esperienza e della precisione ingegneristica necessaria.",
|
||||||
|
"button": "Leggi l'approfondimento sull'eredità di Patrizio"
|
||||||
|
},
|
||||||
|
"CaseStudyModal": {
|
||||||
|
"typeEvent": "Evento / Esposizione",
|
||||||
|
"typeHQ": "Sede Centrale",
|
||||||
|
"typeInstall": "Installazione sul Campo",
|
||||||
|
"keyHighlight": "Punto Saliente",
|
||||||
|
"keyMetric": "Metrica Chiave",
|
||||||
|
"locationStand": "Posizione / Stand",
|
||||||
|
"energyImpact": "Impatto Energetico",
|
||||||
|
"systemStatus": "Stato del Sistema",
|
||||||
|
"scheduled": "In Programma",
|
||||||
|
"concluded": "Concluso",
|
||||||
|
"operational": "Pienamente Operativo",
|
||||||
|
"eventOverview": "Panoramica Evento",
|
||||||
|
"projectChronicle": "Cronaca del Progetto",
|
||||||
|
"pendingData": "[ Dati cronaca in attesa per questo nodo ]",
|
||||||
|
"mediaGallery": "Galleria Media"
|
||||||
|
},
|
||||||
|
"Footer": {
|
||||||
|
"madeInItaly": "Made in Italy",
|
||||||
|
"rights": "Tutti i diritti riservati",
|
||||||
|
"techTitle": "Tecnologia",
|
||||||
|
"appsTitle": "Applicazioni",
|
||||||
|
"companyTitle": "Azienda",
|
||||||
|
"hqTitle": "Sede Centrale",
|
||||||
|
"techSolidState": "RF a Stato Solido",
|
||||||
|
"techMicrowave": "Sistemi a Microonde",
|
||||||
|
"techEfficiency": "Efficienza Energetica",
|
||||||
|
"companyStory": "La nostra Storia",
|
||||||
|
"companyMap": "Rete Globale",
|
||||||
|
"companyNews": "Dentro Flux"
|
||||||
|
}
|
||||||
|
}
|
||||||
169
messages/vec.json
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
{
|
||||||
|
"Navigation": {
|
||||||
|
"applications": "Applicaçion",
|
||||||
|
"globalMap": "Mapa del Mondo",
|
||||||
|
"ourStory": "La Nostra Storia",
|
||||||
|
"parts": "Pessi de Ricambio",
|
||||||
|
"insideFlux": "Drento FLUX"
|
||||||
|
},
|
||||||
|
"HeroReel": {
|
||||||
|
"title1": "Inovaçion,",
|
||||||
|
"title2": "no imitasion.",
|
||||||
|
"description1": "Spingemo l'inovaçion dove i altri i se ferma",
|
||||||
|
"description2": "Solusion RF de nova generasiòn con na preciçion mai vista e l'ecełensa de casa nostra."
|
||||||
|
},
|
||||||
|
"SpareParts": {
|
||||||
|
"title1": "Matriçe dei",
|
||||||
|
"title2": "Pessi.",
|
||||||
|
"description": "Pessi de ricambio e agiornamenti par omini veri firmà FLUX. Par far ndar la machina de RF sempre a tura e par tanto tempo.",
|
||||||
|
"quoteBased": "Dimanda el preso"
|
||||||
|
},
|
||||||
|
"CartDrawer": {
|
||||||
|
"titleSupport": "Asistensa Tecnica",
|
||||||
|
"titleCart": "Careło Operasion",
|
||||||
|
"tabParts": "Pessi de Ricambio",
|
||||||
|
"tabDiagnostic": "Dimanda Diagnostica",
|
||||||
|
"emptyCart": "El careło el xe vodo.",
|
||||||
|
"needHelp": "Te serve asistensa tecnica pitosto?",
|
||||||
|
"quote": "Preventivo",
|
||||||
|
"contactDetails": "Detaji de Contato",
|
||||||
|
"fullName": "Nome e Cognome",
|
||||||
|
"email": "Email de Lavoro",
|
||||||
|
"company": "Dita",
|
||||||
|
"phone": "Tełefono (Se te vołe)",
|
||||||
|
"placeholderDiagnostic": "Spiega cossa che no va, codisi de erore o robe strane...",
|
||||||
|
"placeholderCart": "Altre note pal to ordine...",
|
||||||
|
"attachMedia": "Meti drento Foto o Video (Se te vołe)",
|
||||||
|
"selectFiles": "Sielsi i File",
|
||||||
|
"dragDrop": "Strasina video o foto chive. Masimo 50MB par file.",
|
||||||
|
"gdprAgreement": "Aceto la",
|
||||||
|
"dataPrivacy": "Privacy dei Dati",
|
||||||
|
"gdprDesc": ". I me file i vegnarà anałisà in sicuressa da FLUX Engineering e scancełà bota finìo el laoro.",
|
||||||
|
"estSubtotal": "Subtotale Stimà",
|
||||||
|
"quotePending": "+ Robe in atesa de preventivo",
|
||||||
|
"btnSubmitEngineering": "Manda in Ingegneria",
|
||||||
|
"btnRequestComponents": "Domanda i Pessi",
|
||||||
|
"encrypting": "Drio critar i file...",
|
||||||
|
"connecting": "Drio conetarse...",
|
||||||
|
"successTitle": "Domanda Ricevua",
|
||||||
|
"successDesc1": "El to ticket",
|
||||||
|
"successDesc2": "el xe stà asegnà ai nostri ingegneri.",
|
||||||
|
"closePanel": "Sera el Panel",
|
||||||
|
"modalTitle": "Privacy e Gestion Dati",
|
||||||
|
"modalDesc1": "Come che vol el GDPR de l'Europa, FLUX Srl la tol i to dati e i to file solo par far diagnostica tecnica e preventivi.",
|
||||||
|
"modalDesc2": "Scancełasion Automatica:",
|
||||||
|
"modalDesc3": "Tuti i video e le foto che te meti i xe tegnùi al sicuro e i vegnarà",
|
||||||
|
"modalDesc4": "scancełà par sempre dai nostri server",
|
||||||
|
"modalDesc5": "in t'un bota sol appena che i nostri ingegneri i ga risolto el problema.",
|
||||||
|
"understood": "Capìo tuto"
|
||||||
|
},
|
||||||
|
"HeritagePage": {
|
||||||
|
"backToOverview": "Torna indrìo",
|
||||||
|
"subtitle": "L'eredità de FLUX",
|
||||||
|
"title1": "Costruìr na storia.",
|
||||||
|
"title2": "Inventar el doman.",
|
||||||
|
"emptyState": "Ła storia de drento la xe drio vegner scrita proprio desso nel CMS."
|
||||||
|
},
|
||||||
|
"WhatWeDo": {
|
||||||
|
"subtitle": "Cossa femo",
|
||||||
|
"title": "Svilupemo tecnołogie de radiofrequensa par far ndar forte le industrie de doman.",
|
||||||
|
"desc": "Inovaçion, rendimento e rispeto par l'ambiente in ogni laoro.",
|
||||||
|
"tech": "La nostra tecnołogia a onde pulsà la dopara i campi eletromagnetici par scaldar l'acqua drento i prodoti.",
|
||||||
|
"process": "Co le ciapa ste onde, le molecole le taca vibrar milioni de volte al secondo.",
|
||||||
|
"efficiency": "Sto całore el vien drento subito e in modo conpagno dapartuto, fasendo el laoro tanto più de corsa dei sistemi de na volta.",
|
||||||
|
"servicesSubtitle": "I nostri servisi",
|
||||||
|
"servicesTitle1": "Mioremo i vostri procesi de produsion con ",
|
||||||
|
"servicesTitle2": "vełoicità, preciçion ",
|
||||||
|
"servicesTitle3": "e ",
|
||||||
|
"servicesTitle4": "risparmio de energia.",
|
||||||
|
"servicesDesc": "Grassie a quanto che la xe versaîe la nostra tecnołogia, demo solusion su misura par tanti setori, adatando l'inovaçion RF a quel che serve par davvero."
|
||||||
|
},
|
||||||
|
"AppsDeep": {
|
||||||
|
"subtitle": "La nostra esperiensa",
|
||||||
|
"title1": "Applicaçion ",
|
||||||
|
"title2": "Industriałi.",
|
||||||
|
"moreInfo": "Più informasion"
|
||||||
|
},
|
||||||
|
"GlobalOperations": {
|
||||||
|
"subtitle": "In tuto el mondo",
|
||||||
|
"title1": "Grandi nel mondo.",
|
||||||
|
"title2": "Precisi a casa.",
|
||||||
|
"filterAll": "Rede Global",
|
||||||
|
"filterInstallations": "Impianti",
|
||||||
|
"filterEvents": "Eventi che vien",
|
||||||
|
"filterHQ": "Sede Storica",
|
||||||
|
"filterByApp": "Serca par applicasion:",
|
||||||
|
"networkStatus": "Stato de la Rede",
|
||||||
|
"statusTracking": "Semo drio vardar {count} impianti nel mondo, co i dati in direta.",
|
||||||
|
"statusShowing": "Te si drio vedar i impianti RF par {app} de la nostra rede global.",
|
||||||
|
"helpText": "[ Strasina par girar • Usa la roda par el zoom ]",
|
||||||
|
"statusDetails": "Stato / Detaji",
|
||||||
|
"viewCaseStudy": "Varda el Caso de Studio",
|
||||||
|
"typeEvent": "Fiera / Evento",
|
||||||
|
"typeHQ": "Sede Prinsipałe",
|
||||||
|
"typeInstall": "Impianto sul canpo"
|
||||||
|
},
|
||||||
|
"AppsDashboard": {
|
||||||
|
"subtitle": "Applicaçion RF",
|
||||||
|
"title1": "Fato aposta par el to laoro.",
|
||||||
|
"title2": "Sempre al masimo de l'eficiensa.",
|
||||||
|
"desc": "La nostra tecnołogia RF a stato sołido la xe flessibiłe par organizar el laoro. Sielsi n'applicaçion de soto par vedar come che la cambia i to numari.",
|
||||||
|
"calcROI": "Calcoła el guadagno",
|
||||||
|
"compareTech": "Confronta tecnołogie",
|
||||||
|
"viewSpecs": "Varda i detaji tecnici"
|
||||||
|
},
|
||||||
|
"OurStory": {
|
||||||
|
"subtitle": "Eredità de la dita",
|
||||||
|
"title": "Na storia de inovaçion."
|
||||||
|
},
|
||||||
|
"NewsHub": {
|
||||||
|
"subtitle": "Drento Flux",
|
||||||
|
"title1": "Storie dal ",
|
||||||
|
"title2": "core.",
|
||||||
|
"description": "Novità de tecnołogia, soperte de ingegneria e na ociada a chi che laora par far el futuro de la tecnołogia RF.",
|
||||||
|
"emptyState": "In redasion semo drio preparar la prima storia.",
|
||||||
|
"readFull": "Lèzi tuta la storia",
|
||||||
|
"readMore": "Lèzi de più"
|
||||||
|
},
|
||||||
|
"PatrizioLegacy": {
|
||||||
|
"subtitle": "La nostra eredità",
|
||||||
|
"title1": "40 ani de ecełensa RF.",
|
||||||
|
"title2": "Pensà de novo pal 2026.",
|
||||||
|
"p1_1": "Fondà e guidà da l'Ingegnere ",
|
||||||
|
"p1_2": "Patrizio Grando",
|
||||||
|
"p1_3": ", che el xe tornà drento nel 2023 par ndar vanti con le so idee nove. FLUX Srl la va vanti con quaranta ani de esperiensa che no i ga nesun altro ne la Radiofrequensa.",
|
||||||
|
"p2": "Semo concentrà nel far solusion RF a stato sołido moderne par mercà che i ga voja de inovaçion, dove i altri no i ga l'esperiensa e la preciçion de ingegneria che serve.",
|
||||||
|
"button": "Lèzi l'aprofondimento su l'eredità de Patrizio"
|
||||||
|
},
|
||||||
|
"CaseStudyModal": {
|
||||||
|
"typeEvent": "Fiera / Evento",
|
||||||
|
"typeHQ": "Sede Prinsipałe",
|
||||||
|
"typeInstall": "Impianto sul canpo",
|
||||||
|
"keyHighlight": "Punto ciave",
|
||||||
|
"keyMetric": "Numaro ciave",
|
||||||
|
"locationStand": "Posto / Stand",
|
||||||
|
"energyImpact": "Impato energetico",
|
||||||
|
"systemStatus": "Stato del sistema",
|
||||||
|
"scheduled": "In programa",
|
||||||
|
"concluded": "Finìo",
|
||||||
|
"operational": "In fonsion",
|
||||||
|
"eventOverview": "Detaji de l'evento",
|
||||||
|
"projectChronicle": "Storia del projeto",
|
||||||
|
"pendingData": "[ Dati de la storia drio rivar par sto nodo ]",
|
||||||
|
"mediaGallery": "Gałeria de foto"
|
||||||
|
},
|
||||||
|
"Footer": {
|
||||||
|
"madeInItaly": "Fato in Itaia",
|
||||||
|
"rights": "Tuti i driti riservà",
|
||||||
|
"techTitle": "Tecnołogia",
|
||||||
|
"appsTitle": "Applicaçion",
|
||||||
|
"companyTitle": "Dita",
|
||||||
|
"hqTitle": "Sede Prinsipałe",
|
||||||
|
"techSolidState": "RF a Stato Sołido",
|
||||||
|
"techMicrowave": "Sistemi Microwave",
|
||||||
|
"techEfficiency": "Risparmio Energia",
|
||||||
|
"companyStory": "La nostra Storia",
|
||||||
|
"companyMap": "Rede Global",
|
||||||
|
"companyNews": "Drento Flux"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,19 @@
|
|||||||
import type { NextConfig } from "next";
|
import createNextIntlPlugin from 'next-intl/plugin';
|
||||||
|
|
||||||
const nextConfig: NextConfig = {
|
// Le indicamos dónde estará nuestro archivo principal de configuración
|
||||||
/* config options here */
|
const withNextIntl = createNextIntlPlugin('./src/i18n/request.ts');
|
||||||
|
|
||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {
|
||||||
|
// Esta línea es la magia para Docker: empaqueta solo lo necesario
|
||||||
|
output: "standalone" as const,
|
||||||
|
images: {
|
||||||
|
qualities: [75, 90, 100], // 🔥 Agrega esto
|
||||||
|
},
|
||||||
|
// Opcional, pero recomendado para mantener un código ultra limpio
|
||||||
|
reactStrictMode: true,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nextConfig;
|
// Envolvemos la configuración con el plugin de internacionalización
|
||||||
|
export default withNextIntl(nextConfig);
|
||||||
107
nginx/conf.d/flux-ssl.conf
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# FLUX SRL — Nginx SSL Configuration (rf-flux.com)
|
||||||
|
# Swap this in after running certbot:
|
||||||
|
# cp nginx/conf.d/flux-ssl.conf nginx/conf.d/flux.conf
|
||||||
|
# docker compose restart nginx
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
|
||||||
|
limit_req_zone $binary_remote_addr zone=login:10m rate=3r/m;
|
||||||
|
|
||||||
|
upstream nextjs {
|
||||||
|
server app:3000;
|
||||||
|
keepalive 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTP → HTTPS redirect
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name rf-flux.com www.rf-flux.com;
|
||||||
|
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
root /var/www/certbot;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTPS
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name rf-flux.com www.rf-flux.com;
|
||||||
|
|
||||||
|
# SSL Certificates
|
||||||
|
ssl_certificate /etc/letsencrypt/live/rf-flux.com/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/rf-flux.com/privkey.pem;
|
||||||
|
|
||||||
|
# SSL Hardening (A+ on SSL Labs)
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
ssl_session_timeout 1d;
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
ssl_session_tickets off;
|
||||||
|
ssl_stapling on;
|
||||||
|
ssl_stapling_verify on;
|
||||||
|
|
||||||
|
# HSTS (2 years)
|
||||||
|
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
|
||||||
|
|
||||||
|
# Content Security Policy
|
||||||
|
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: blob:; connect-src 'self' https://api.openai.com; media-src 'self'; object-src 'none'; frame-ancestors 'self';" always;
|
||||||
|
|
||||||
|
location /_next/static/ {
|
||||||
|
proxy_pass http://nextjs;
|
||||||
|
expires 365d;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /footage/ {
|
||||||
|
proxy_pass http://nextjs;
|
||||||
|
expires 30d;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /hq-command/ {
|
||||||
|
limit_req zone=login burst=5 nodelay;
|
||||||
|
proxy_pass http://nextjs;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/chat {
|
||||||
|
limit_req zone=api burst=20 nodelay;
|
||||||
|
proxy_pass http://nextjs;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Connection '';
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_cache off;
|
||||||
|
proxy_read_timeout 120s;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/health {
|
||||||
|
proxy_pass http://nextjs;
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://nextjs;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
}
|
||||||
81
nginx/conf.d/flux.conf
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# FLUX SRL — Nginx Site Configuration
|
||||||
|
# Phase 1: HTTP only (SSL added after certbot runs)
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
|
||||||
|
limit_req_zone $binary_remote_addr zone=login:10m rate=3r/m;
|
||||||
|
|
||||||
|
upstream nextjs {
|
||||||
|
server app:3000;
|
||||||
|
keepalive 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name rf-flux.com www.rf-flux.com;
|
||||||
|
|
||||||
|
# Let's Encrypt challenge (keep this even after SSL)
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
root /var/www/certbot;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Static assets: Next.js hashed (immutable cache)
|
||||||
|
location /_next/static/ {
|
||||||
|
proxy_pass http://nextjs;
|
||||||
|
expires 365d;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Static assets: footage, GLB models
|
||||||
|
location /footage/ {
|
||||||
|
proxy_pass http://nextjs;
|
||||||
|
expires 30d;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# CMS Admin (strict rate limiting)
|
||||||
|
location /hq-command/ {
|
||||||
|
limit_req zone=login burst=5 nodelay;
|
||||||
|
proxy_pass http://nextjs;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
# FluxAI Chat API (streaming + rate limited)
|
||||||
|
location /api/chat {
|
||||||
|
limit_req zone=api burst=20 nodelay;
|
||||||
|
proxy_pass http://nextjs;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Connection '';
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_cache off;
|
||||||
|
proxy_read_timeout 120s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
location /api/health {
|
||||||
|
proxy_pass http://nextjs;
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Default
|
||||||
|
location / {
|
||||||
|
proxy_pass http://nextjs;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
}
|
||||||
42
nginx/nginx.conf
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
user nginx;
|
||||||
|
worker_processes auto;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
multi_accept on;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
tcp_nopush on;
|
||||||
|
tcp_nodelay on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
types_hash_max_size 2048;
|
||||||
|
client_max_body_size 50M;
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_proxied any;
|
||||||
|
gzip_comp_level 6;
|
||||||
|
gzip_min_length 1000;
|
||||||
|
gzip_types text/plain text/css application/json application/javascript
|
||||||
|
text/xml application/xml application/xml+rss text/javascript
|
||||||
|
image/svg+xml application/wasm;
|
||||||
|
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||||
|
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent"';
|
||||||
|
access_log /var/log/nginx/access.log main;
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
}
|
||||||
4215
package-lock.json
generated
36
package.json
@ -9,17 +9,45 @@
|
|||||||
"lint": "eslint"
|
"lint": "eslint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@ai-sdk/openai": "^3.0.41",
|
||||||
|
"@ai-sdk/react": "^3.0.118",
|
||||||
|
"@prisma/adapter-pg": "^7.5.0",
|
||||||
|
"@prisma/client": "^7.5.0",
|
||||||
|
"@react-three/drei": "^10.7.7",
|
||||||
|
"@react-three/fiber": "^9.5.0",
|
||||||
|
"@types/nodemailer": "^7.0.11",
|
||||||
|
"ai": "^6.0.116",
|
||||||
|
"bcryptjs": "^3.0.3",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"framer-motion": "^12.35.2",
|
||||||
|
"jose": "^6.2.1",
|
||||||
|
"lucide-react": "^0.577.0",
|
||||||
"next": "16.1.6",
|
"next": "16.1.6",
|
||||||
"react": "19.2.3",
|
"next-intl": "^4.8.3",
|
||||||
"react-dom": "19.2.3"
|
"nodemailer": "^8.0.2",
|
||||||
|
"pg": "^8.20.0",
|
||||||
|
"qrcode": "^1.5.4",
|
||||||
|
"react": "19.2.4",
|
||||||
|
"react-dom": "19.2.4",
|
||||||
|
"resend": "^6.9.3",
|
||||||
|
"speakeasy": "^2.0.0",
|
||||||
|
"tailwind-merge": "^3.5.0",
|
||||||
|
"three": "^0.183.2",
|
||||||
|
"zod": "^4.3.6",
|
||||||
|
"zustand": "^5.0.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "^4",
|
"@tailwindcss/postcss": "^4",
|
||||||
"@types/node": "^20",
|
"@types/bcryptjs": "^3.0.0",
|
||||||
|
"@types/node": "^25",
|
||||||
|
"@types/pg": "^8.18.0",
|
||||||
|
"@types/qrcode": "^1.5.6",
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
"eslint": "^9",
|
"@types/speakeasy": "^2.0.10",
|
||||||
|
"eslint": "^10",
|
||||||
"eslint-config-next": "16.1.6",
|
"eslint-config-next": "16.1.6",
|
||||||
|
"prisma": "^7.5.0",
|
||||||
"tailwindcss": "^4",
|
"tailwindcss": "^4",
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
}
|
}
|
||||||
|
|||||||
15
prisma.config.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
// This file was generated by Prisma and assumes you have installed the following:
|
||||||
|
// npm install --save-dev prisma dotenv
|
||||||
|
import "dotenv/config";
|
||||||
|
import { defineConfig, env } from "prisma/config";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
schema: "prisma/schema.prisma",
|
||||||
|
migrations: {
|
||||||
|
path: "prisma/migrations",
|
||||||
|
},
|
||||||
|
datasource: {
|
||||||
|
url: env("DATABASE_URL"),
|
||||||
|
},
|
||||||
|
});
|
||||||
BIN
prisma/dev.db
Normal file
214
prisma/migrations/20260306154126_init_postgresql/migration.sql
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
-- CreateSchema
|
||||||
|
CREATE SCHEMA IF NOT EXISTS "public";
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "AdminUser" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"username" TEXT NOT NULL,
|
||||||
|
"email" TEXT,
|
||||||
|
"passwordHash" TEXT NOT NULL,
|
||||||
|
"twoFactorSecret" TEXT,
|
||||||
|
"is2FAEnabled" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "AdminUser_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "GlobalNode" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"title" TEXT NOT NULL,
|
||||||
|
"location" TEXT NOT NULL,
|
||||||
|
"lat" DOUBLE PRECISION NOT NULL,
|
||||||
|
"lon" DOUBLE PRECISION NOT NULL,
|
||||||
|
"nodeType" TEXT NOT NULL DEFAULT 'installation',
|
||||||
|
"application" TEXT NOT NULL,
|
||||||
|
"stats" TEXT NOT NULL,
|
||||||
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
"projectOverview" TEXT,
|
||||||
|
"energySavings" TEXT,
|
||||||
|
"eventDate" TIMESTAMP(3),
|
||||||
|
"mediaFileName" TEXT,
|
||||||
|
"galleryJson" TEXT DEFAULT '[]',
|
||||||
|
"videosJson" TEXT DEFAULT '[]',
|
||||||
|
"specificDatasheetJson" TEXT DEFAULT '[]',
|
||||||
|
"model3DPath" TEXT,
|
||||||
|
"rendersJson" TEXT DEFAULT '[]',
|
||||||
|
"model3DDimsJson" TEXT,
|
||||||
|
"translationsJson" TEXT DEFAULT '{}',
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "GlobalNode_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "Application" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"slug" TEXT NOT NULL,
|
||||||
|
"title" TEXT NOT NULL,
|
||||||
|
"subtitle" TEXT NOT NULL,
|
||||||
|
"category" TEXT NOT NULL,
|
||||||
|
"shortDescription" TEXT NOT NULL DEFAULT 'Learn more about this FLUX RF technology application.',
|
||||||
|
"heroDescription" TEXT NOT NULL,
|
||||||
|
"sectionsJson" TEXT NOT NULL,
|
||||||
|
"advantagesJson" TEXT NOT NULL,
|
||||||
|
"datasheetJson" TEXT NOT NULL,
|
||||||
|
"dashboardMetricsJson" TEXT DEFAULT '[]',
|
||||||
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
"translationsJson" TEXT DEFAULT '{}',
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "Application_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "TimelineEvent" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"year" TEXT NOT NULL,
|
||||||
|
"title" TEXT NOT NULL,
|
||||||
|
"description" TEXT NOT NULL,
|
||||||
|
"order" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
"translationsJson" TEXT DEFAULT '{}',
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "TimelineEvent_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "NewsArticle" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"slug" TEXT NOT NULL,
|
||||||
|
"title" TEXT NOT NULL,
|
||||||
|
"excerpt" TEXT NOT NULL,
|
||||||
|
"content" TEXT NOT NULL,
|
||||||
|
"coverImage" TEXT,
|
||||||
|
"category" TEXT NOT NULL DEFAULT 'News',
|
||||||
|
"publishedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
"order" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"galleryJson" TEXT DEFAULT '[]',
|
||||||
|
"linkedinUrl" TEXT,
|
||||||
|
"translationsJson" TEXT DEFAULT '{}',
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "NewsArticle_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "HeritageSection" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"type" TEXT NOT NULL DEFAULT 'text',
|
||||||
|
"title" TEXT,
|
||||||
|
"content" TEXT,
|
||||||
|
"mediaUrl" TEXT,
|
||||||
|
"order" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"translationsJson" TEXT DEFAULT '{}',
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "HeritageSection_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "SparePart" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"sku" TEXT NOT NULL,
|
||||||
|
"title" TEXT NOT NULL,
|
||||||
|
"description" TEXT NOT NULL,
|
||||||
|
"mediaJson" TEXT DEFAULT '[]',
|
||||||
|
"specsJson" TEXT DEFAULT '[]',
|
||||||
|
"price" DOUBLE PRECISION,
|
||||||
|
"showPrice" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
"translationsJson" TEXT DEFAULT '{}',
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "SparePart_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "OperationsSignal" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"ticketId" TEXT NOT NULL,
|
||||||
|
"ticketNumber" SERIAL NOT NULL,
|
||||||
|
"type" TEXT NOT NULL,
|
||||||
|
"status" TEXT NOT NULL DEFAULT 'PENDING',
|
||||||
|
"clientName" TEXT NOT NULL,
|
||||||
|
"clientEmail" TEXT NOT NULL,
|
||||||
|
"clientCompany" TEXT NOT NULL,
|
||||||
|
"clientPhone" TEXT,
|
||||||
|
"message" TEXT,
|
||||||
|
"cartPayload" TEXT DEFAULT '[]',
|
||||||
|
"attachedFiles" TEXT DEFAULT '[]',
|
||||||
|
"aiAnalysis" TEXT,
|
||||||
|
"emailSentTo" TEXT,
|
||||||
|
"emailSentAt" TIMESTAMP(3),
|
||||||
|
"emailError" TEXT,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "OperationsSignal_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "NotificationRoute" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"routeType" TEXT NOT NULL,
|
||||||
|
"emails" TEXT NOT NULL,
|
||||||
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "NotificationRoute_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "PageContent" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"slug" TEXT NOT NULL,
|
||||||
|
"title" TEXT NOT NULL,
|
||||||
|
"subtitle" TEXT,
|
||||||
|
"description" TEXT,
|
||||||
|
"translationsJson" TEXT DEFAULT '{}',
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "PageContent_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "AdminUser_username_key" ON "AdminUser"("username");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "Application_slug_key" ON "Application"("slug");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "NewsArticle_slug_key" ON "NewsArticle"("slug");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "SparePart_sku_key" ON "SparePart"("sku");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "OperationsSignal_ticketId_key" ON "OperationsSignal"("ticketId");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "OperationsSignal_type_idx" ON "OperationsSignal"("type");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "OperationsSignal_status_idx" ON "OperationsSignal"("status");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "OperationsSignal_createdAt_idx" ON "OperationsSignal"("createdAt" DESC);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "NotificationRoute_routeType_key" ON "NotificationRoute"("routeType");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "PageContent_slug_key" ON "PageContent"("slug");
|
||||||
|
|
||||||
270
prisma/schema.prisma
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
// This is your Prisma schema file,
|
||||||
|
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||||
|
|
||||||
|
generator client {
|
||||||
|
provider = "prisma-client-js"
|
||||||
|
}
|
||||||
|
|
||||||
|
datasource db {
|
||||||
|
provider = "postgresql"
|
||||||
|
//url = env("DATABASE_URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// 1. BÓVEDA DE SEGURIDAD (Usuarios del CMS)
|
||||||
|
// ------------------------------------------------------
|
||||||
|
model AdminUser {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
username String @unique
|
||||||
|
email String? // 🔥 NUEVO CAMPO: Correo del administrador
|
||||||
|
passwordHash String
|
||||||
|
twoFactorSecret String?
|
||||||
|
is2FAEnabled Boolean @default(false)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// 2. EL GLOBO HOLOGRÁFICO (Nodos y Casos de Estudio Profundos)
|
||||||
|
// ------------------------------------------------------
|
||||||
|
model GlobalNode {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
title String // Ej: "Toray Advanced Textiles"
|
||||||
|
location String
|
||||||
|
// Ej: "Tokyo, Japan"
|
||||||
|
lat Float // Ej: 35.6895
|
||||||
|
lon Float // Ej: 139.6917
|
||||||
|
|
||||||
|
// Taxonomía
|
||||||
|
nodeType String @default("installation") // "installation", "event", "hq"
|
||||||
|
application String // Ej: "textile-drying", "hq", "event"
|
||||||
|
stats String // Ej: "2,400 kg/h throughput"
|
||||||
|
isActive Boolean @default(true) // Permite ocultar un nodo sin borrarlo
|
||||||
|
|
||||||
|
// 📖 GEO-CHRONICLE (THE STORY)
|
||||||
|
projectOverview String? // El Artículo completo / Resumen del evento (Markdown)
|
||||||
|
energySavings String? // Métrica (Ej: "-45% vs Conventional" o "Stand 4B")
|
||||||
|
eventDate DateTime?// Fecha para controlar si el evento es pasado o futuro
|
||||||
|
|
||||||
|
// 🔥 NUEVOS CAMPOS FASE 1: MULTIMEDIA Y DATASHEET ESPECÍFICO 🔥
|
||||||
|
mediaFileName String? // Imagen de Portada principal
|
||||||
|
galleryJson String? @default("[]") // Array de imágenes extra
|
||||||
|
videosJson String? @default("[]") // Links a videos reales
|
||||||
|
specificDatasheetJson String? @default("[]") // Ficha técnica de ESTA máquina
|
||||||
|
model3DPath String? // Ruta al archivo GLB/USDZ
|
||||||
|
rendersJson String? @default("[]") // Renders 3D fotorrealistas
|
||||||
|
model3DDimsJson String? // Dimensiones físicas AR: { w, h, d, unit, weight }
|
||||||
|
|
||||||
|
// 🌍 MOTOR DE TRADUCCIONES
|
||||||
|
translationsJson String? @default("{}")
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// 3. LA BASE DE CONOCIMIENTO (Páginas de Aplicaciones)
|
||||||
|
// ------------------------------------------------------
|
||||||
|
model Application {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
slug String @unique // Ej: "textile-drying" (Debe coincidir con la URL)
|
||||||
|
title String
|
||||||
|
subtitle String
|
||||||
|
category String
|
||||||
|
|
||||||
|
// 🔥 NUEVO: La descripción corta para las tarjetas de la página principal
|
||||||
|
shortDescription String @default("Learn more about this FLUX RF technology application.")
|
||||||
|
heroDescription String // Recibirá MARKDOWN para la teoría científica general
|
||||||
|
|
||||||
|
// JSONs para estructuras complejas
|
||||||
|
sectionsJson String
|
||||||
|
advantagesJson String
|
||||||
|
datasheetJson String
|
||||||
|
|
||||||
|
// Métricas Rápidas para el Dashboard
|
||||||
|
dashboardMetricsJson String? @default("[]")
|
||||||
|
isActive Boolean @default(true) // 🔥 NUEVO: Para poder ocultarlas
|
||||||
|
|
||||||
|
// 🌍 MOTOR DE TRADUCCIONES
|
||||||
|
translationsJson String? @default("{}")
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// 4. NUESTRA HISTORIA (Línea de tiempo de la empresa)
|
||||||
|
// ------------------------------------------------------
|
||||||
|
model TimelineEvent {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
year String // Ej: "1978" o "1990s"
|
||||||
|
title String
|
||||||
|
description String
|
||||||
|
order Int @default(0) // Para ordenar cronológicamente
|
||||||
|
isActive Boolean @default(true)
|
||||||
|
|
||||||
|
// 🌍 MOTOR DE TRADUCCIONES
|
||||||
|
translationsJson String? @default("{}")
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// 5. INSIDE FLUX (Motor de Noticias y Detrás de Cámaras)
|
||||||
|
// ------------------------------------------------------
|
||||||
|
model NewsArticle {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
slug String @unique
|
||||||
|
title String
|
||||||
|
excerpt String // Resumen corto para la tarjeta
|
||||||
|
content String // El artículo completo (Markdown)
|
||||||
|
coverImage String? // Ej: "team-meeting.jpg"
|
||||||
|
category String @default("News")
|
||||||
|
publishedAt DateTime @default(now())
|
||||||
|
isActive Boolean @default(true)
|
||||||
|
|
||||||
|
// Editor avanzado
|
||||||
|
order Int @default(0) // Para ordenar las noticias
|
||||||
|
galleryJson String? @default("[]") // Galería de imágenes extra
|
||||||
|
linkedinUrl String? // Enlace oficial para LinkedIn
|
||||||
|
|
||||||
|
// 🌍 MOTOR DE TRADUCCIONES
|
||||||
|
translationsJson String? @default("{}")
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// 6. OUR HERITAGE (La Historia Profunda de Patrizio)
|
||||||
|
// ------------------------------------------------------
|
||||||
|
model HeritageSection {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
type String @default("text") // "text", "image", "video"
|
||||||
|
title String?
|
||||||
|
content String? // Párrafos de la historia
|
||||||
|
mediaUrl String? // Ej: "patrizio-1980.jpg" o enlace de YouTube
|
||||||
|
order Int @default(0) // Para ordenar cómo se lee la página
|
||||||
|
|
||||||
|
// 🌍 MOTOR DE TRADUCCIONES
|
||||||
|
translationsJson String? @default("{}")
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// 7. COMPONENT MATRIX (Catálogo de Repuestos)
|
||||||
|
// ------------------------------------------------------
|
||||||
|
model SparePart {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
sku String @unique // Identificador único / Referencia (Ej: "FLX-GEN-001")
|
||||||
|
title String // Nombre de la pieza en Inglés
|
||||||
|
description String // Descripción técnica / Función (Markdown)
|
||||||
|
|
||||||
|
// Multimedia & Ficha Técnica
|
||||||
|
mediaJson String? @default("[]") // Imágenes, videos, renders 3D
|
||||||
|
specsJson String? @default("[]") // Array de métricas [{label: "Voltage", value: "24V"}]
|
||||||
|
|
||||||
|
// Estrategia de Ventas
|
||||||
|
price Float? // Precio (Opcional)
|
||||||
|
showPrice Boolean @default(false) // Interruptor: true = mostrar precio, false = "Request Quote"
|
||||||
|
isActive Boolean @default(true) // Para ocultar repuestos descontinuados
|
||||||
|
|
||||||
|
// 🌍 MOTOR DE TRADUCCIONES (Integración con aiTranslator.ts)
|
||||||
|
translationsJson String? @default("{}")
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// 8. OPERATIONS INBOX (Signal Hub - Mesa de Ayuda y Órdenes)
|
||||||
|
// ------------------------------------------------------
|
||||||
|
model OperationsSignal {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
ticketId String @unique
|
||||||
|
ticketNumber Int @default(autoincrement()) // Sequential for analytics
|
||||||
|
type String // "ORDER", "DIAGNOSTIC", "CONSULTATION"
|
||||||
|
status String @default("PENDING") // "PENDING", "REVIEWING", "RESOLVED"
|
||||||
|
|
||||||
|
// Client data
|
||||||
|
clientName String
|
||||||
|
clientEmail String
|
||||||
|
clientCompany String
|
||||||
|
clientPhone String?
|
||||||
|
message String?
|
||||||
|
|
||||||
|
// Payloads
|
||||||
|
cartPayload String? @default("[]")
|
||||||
|
attachedFiles String? @default("[]")
|
||||||
|
aiAnalysis String?
|
||||||
|
|
||||||
|
// Email delivery tracking
|
||||||
|
emailSentTo String? // Comma-separated list of emails that received notification
|
||||||
|
emailSentAt DateTime? // When the email was dispatched
|
||||||
|
emailError String? // Error message if email failed
|
||||||
|
|
||||||
|
// 🔥 NUEVO: Relación opcional con el Cliente Registrado (Para el futuro CRM)
|
||||||
|
clientId String?
|
||||||
|
client ClientUser? @relation(fields: [clientId], references: [id])
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
@@index([type])
|
||||||
|
@@index([status])
|
||||||
|
@@index([createdAt(sort: Desc)])
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// 9. RUTAS DE NOTIFICACIÓN (Gestión de Emails)
|
||||||
|
// ------------------------------------------------------
|
||||||
|
model NotificationRoute {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
routeType String @unique // Ej: "ORDER", "DIAGNOSTIC", "CONSULTATION"
|
||||||
|
emails String // Correos separados por coma (Ej: "sales@fluxsrl.com, tech@fluxsrl.com")
|
||||||
|
isActive Boolean @default(true)
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// 10. PAGE CONTENT (Metadata y Textos de Páginas)
|
||||||
|
// ------------------------------------------------------
|
||||||
|
model PageContent {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
slug String @unique // Identificador de la página (Ej: "parts-catalog")
|
||||||
|
title String
|
||||||
|
subtitle String?
|
||||||
|
description String?
|
||||||
|
|
||||||
|
// 🌍 MOTOR DE TRADUCCIONES
|
||||||
|
translationsJson String? @default("{}")
|
||||||
|
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// 11. CLIENT PORTAL (Usuarios B2B Aprobados) 🔥 NUEVO
|
||||||
|
// ------------------------------------------------------
|
||||||
|
model ClientUser {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
email String @unique
|
||||||
|
passwordHash String
|
||||||
|
fullName String
|
||||||
|
companyName String
|
||||||
|
phone String?
|
||||||
|
|
||||||
|
// Control de Acceso
|
||||||
|
isApproved Boolean @default(false) // Requiere aprobación del Admin
|
||||||
|
|
||||||
|
// Historial de Compras/Tickets
|
||||||
|
signals OperationsSignal[]
|
||||||
|
|
||||||
|
lastLoginAt DateTime?
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
BIN
public/Documentos conocimiento/Como esta.gif
Normal file
|
After Width: | Height: | Size: 34 MiB |
BIN
public/Documentos conocimiento/FLUX - SMART DRYERS scription.pdf
Normal file
BIN
public/Documentos conocimiento/Technology RF for cannabis.pdf
Normal file
BIN
public/LogosFlux.sketch
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
public/applications/digital-printing/DJI_0030.JPG
Normal file
|
After Width: | Height: | Size: 3.9 MiB |
BIN
public/applications/digital-printing/DJI_0032.JPG
Normal file
|
After Width: | Height: | Size: 4.2 MiB |
BIN
public/applications/digital-printing/DJI_0035.JPG
Normal file
|
After Width: | Height: | Size: 3.9 MiB |
BIN
public/applications/digital-printing/DJI_0036.JPG
Normal file
|
After Width: | Height: | Size: 3.9 MiB |
BIN
public/applications/digital-printing/DJI_0038.JPG
Normal file
|
After Width: | Height: | Size: 3.8 MiB |
BIN
public/applications/digital-printing/IMG-20240524-WA0056.jpg
Normal file
|
After Width: | Height: | Size: 133 KiB |
BIN
public/applications/digital-printing/IMG-20240524-WA0069.jpg
Normal file
|
After Width: | Height: | Size: 297 KiB |
BIN
public/applications/digital-printing/IMG-20240524-WA0071.jpg
Normal file
|
After Width: | Height: | Size: 146 KiB |
BIN
public/applications/digital-printing/P1013668.JPG
Normal file
|
After Width: | Height: | Size: 10 MiB |
BIN
public/applications/digital-printing/P1013670.JPG
Normal file
|
After Width: | Height: | Size: 11 MiB |
BIN
public/applications/digital-printing/P1013671.JPG
Normal file
|
After Width: | Height: | Size: 12 MiB |
BIN
public/applications/food-defrosting/a new beginning photo.png
Normal file
|
After Width: | Height: | Size: 36 MiB |
BIN
public/applications/inkjet-printing/Tifani_Render01.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/applications/nuevaapplicationi/images/checker.png
Normal file
|
After Width: | Height: | Size: 147 KiB |
|
After Width: | Height: | Size: 2.1 MiB |
BIN
public/applications/nuevaapplicationi/images/tifani_render03.png
Normal file
|
After Width: | Height: | Size: 889 KiB |
|
After Width: | Height: | Size: 406 KiB |
BIN
public/applications/textile-drying/Tifani_Render01.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/applications/textile-drying/Tifani_Render02.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/applications/textile-drying/Tifani_Render03.png
Normal file
|
After Width: | Height: | Size: 889 KiB |
BIN
public/applications/textile-drying/background1.png
Normal file
|
After Width: | Height: | Size: 730 KiB |
BIN
public/applications/textile-drying/vertical fabric dryer.mp4
Normal file
BIN
public/cases/TatiAntonePatri.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
public/cases/Tifani_Render01.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/cases/Tifani_Render02.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/cases/Tifani_Render03.png
Normal file
|
After Width: | Height: | Size: 889 KiB |
BIN
public/cases/Untitled 7.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
public/cases/cordones/dreamlightslogo.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
public/cases/cordones/images/IMG-20240524-WA0001.jpg
Normal file
|
After Width: | Height: | Size: 166 KiB |
BIN
public/cases/cordones/images/IMG-20240524-WA0005.jpg
Normal file
|
After Width: | Height: | Size: 324 KiB |
BIN
public/cases/cordones/images/IMG-20240524-WA0007.jpg
Normal file
|
After Width: | Height: | Size: 341 KiB |
BIN
public/cases/cordones/images/IMG-20240524-WA0009.jpg
Normal file
|
After Width: | Height: | Size: 107 KiB |
BIN
public/cases/cordones/images/IMG-20240524-WA0017.jpg
Normal file
|
After Width: | Height: | Size: 155 KiB |
BIN
public/cases/cordones/images/IMG-20240524-WA0028.jpg
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
public/cases/cordones/images/IMG-20240524-WA0031.jpg
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
public/cases/cordones/images/IMG-20240524-WA0039.jpg
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
public/cases/cordones/images/IMG-20240524-WA0043.jpg
Normal file
|
After Width: | Height: | Size: 163 KiB |
BIN
public/cases/cordones/images/IMG-20240524-WA0049.jpg
Normal file
|
After Width: | Height: | Size: 183 KiB |
BIN
public/cases/cordones/images/IMG-20240524-WA0052.jpg
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
public/cases/cordones/images/IMG-20240524-WA0079.jpg
Normal file
|
After Width: | Height: | Size: 193 KiB |
BIN
public/cases/cordones/models/mechanical_spider.glb
Normal file
BIN
public/cases/cordones/models/mechanical_spider.usdz
Normal file
BIN
public/cases/cordones/renders/tifani_render01.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/cases/cordones/renders/tifani_render02.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/cases/cordones/renders/tifani_render03.png
Normal file
|
After Width: | Height: | Size: 889 KiB |
BIN
public/cases/cordones/videos/vertical-fabric-dryer.mp4
Normal file
BIN
public/cases/medellin-machine.jpg
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
public/cases/models/Mechanical_Spider.usdz
Normal file
BIN
public/cases/models/mechanical_spider.glb
Normal file
BIN
public/cases/padova/models/mechanical_spider.glb
Normal file
BIN
public/cases/padova/tatiantonepatri.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
public/cases/portada.webp
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
public/cases/videos/vertical fabric dryer.mp4
Normal file
BIN
public/cases/videos/videoDemo.mp4
Normal file
BIN
public/flux-logo.png
Normal file
|
After Width: | Height: | Size: 81 KiB |
20
public/flux-logo.svg
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="1194px" height="956px" viewBox="0 0 1194 956" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>Group</title>
|
||||||
|
<defs>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="31.1476469%" id="linearGradient-1">
|
||||||
|
<stop stop-color="#8BD6FF" offset="0%"></stop>
|
||||||
|
<stop stop-color="#8BD6FF" offset="84.1947115%"></stop>
|
||||||
|
<stop stop-color="#0063B5" offset="88.548951%"></stop>
|
||||||
|
<stop stop-color="#0063B5" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="Group" transform="translate(0.3284, 16.75)">
|
||||||
|
<rect id="Rectangle" fill="#0063B5" transform="translate(91, 324.5698) rotate(45) translate(-91, -324.5698)" x="27" y="260.569805" width="128" height="128"></rect>
|
||||||
|
<rect id="Rectangle-Copy" fill="#0063B5" transform="translate(1103, 324.5698) rotate(45) translate(-1103, -324.5698)" x="1039" y="260.569805" width="128" height="128"></rect>
|
||||||
|
<path d="M90.9215729,325.5 L469.671573,325.5 L469.671573,190.75 C470.171573,171.583333 481.004906,162 502.171573,162 C523.33824,162 533.921573,171.583333 533.921573,190.75 L533.921573,524 C537.58824,542 549.004906,551 568.171573,551 C587.33824,551 598.83824,542 602.671573,524 L602.671573,28.5 C601.83824,9.5 612.421573,0 634.421573,0 C656.421573,0 667.421573,9.5 667.421573,28.5 L667.421573,416 C667.754906,438.333333 678.33824,449.5 699.171573,449.5 C720.004906,449.5 730.421573,438.333333 730.421573,416 L730.421573,325.5 L1102.92157,325.5" id="Path" stroke="#0063B5" stroke-width="33"></path>
|
||||||
|
<path d="M231.171573,264 C231.171573,371.333333 231.171573,478.666667 231.171573,586 C231.171573,724.75 355.171573,938.25 598.671573,938.25 C842.171573,938.25 968.171573,710.75 965.421573,586 C963.71246,508.468428 963.596656,401.24337 965.074162,264.324825 L965.07415,264.324825 C965.253545,247.757254 951.968304,234.181154 935.400733,234.001759 C935.292365,234.000585 935.183992,233.999999 935.075618,234 L822.921573,234 C806.35303,234 792.921573,247.431458 792.921573,264 C792.921573,371.333333 792.921573,478.666667 792.921573,586 C792.921573,662 711.921573,768.25 598.671573,768.25 C485.421573,768.25 408.421573,679.25 400.421573,586 C400.421573,478.666667 400.421573,371.333333 400.421573,264 C400.421573,247.431458 386.990115,234 370.421573,234 L261.171573,234 C244.60303,234 231.171573,247.431458 231.171573,264 Z" id="Path" stroke="#979797" fill="url(#linearGradient-1)"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.6 KiB |
BIN
public/footage/FluxCanvaEdit.pxd
Normal file
BIN
public/footage/dataArticles/RFWorks.jpg
Normal file
|
After Width: | Height: | Size: 281 KiB |
BIN
public/footage/main/01_PATRIZIO_BODY.jpg
Normal file
|
After Width: | Height: | Size: 181 KiB |
BIN
public/footage/main/Artboard.png
Normal file
|
After Width: | Height: | Size: 3.7 MiB |
|
After Width: | Height: | Size: 95 KiB |
BIN
public/footage/main/IMG-20240524-WA0009.jpg
Normal file
|
After Width: | Height: | Size: 107 KiB |
BIN
public/footage/main/P1013692.JPG
Normal file
|
After Width: | Height: | Size: 11 MiB |
BIN
public/footage/main/a new beginning photo.png
Normal file
|
After Width: | Height: | Size: 36 MiB |
BIN
public/footage/main/foto ing. grando-woweare.jpg
Normal file
|
After Width: | Height: | Size: 19 MiB |
BIN
public/footage/main/img-YZ99rg45lycoQvJO.jpg
Normal file
|
After Width: | Height: | Size: 644 KiB |
BIN
public/heritage/P1013671.JPG
Normal file
|
After Width: | Height: | Size: 12 MiB |
BIN
public/heritage/patrizio.png
Normal file
|
After Width: | Height: | Size: 3.7 MiB |
BIN
public/heritage/videoDemo.mp4
Normal file
BIN
public/logoEmail.png
Normal file
|
After Width: | Height: | Size: 66 KiB |