diff --git a/Dockerfile b/Dockerfile index 4129504..c3217c8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,11 +7,23 @@ ARG NEXT_PUBLIC_BASE_URL ARG NEXT_PUBLIC_TARGET ARG UMAMI_API_ENDPOINT ARG NPM_TOKEN +ARG S3_ENDPOINT +ARG S3_ACCESS_KEY +ARG S3_SECRET_KEY +ARG S3_BUCKET +ARG S3_REGION +ARG S3_PREFIX # Environment variables for Next.js build ENV NEXT_PUBLIC_BASE_URL=$NEXT_PUBLIC_BASE_URL ENV NEXT_PUBLIC_TARGET=$NEXT_PUBLIC_TARGET ENV UMAMI_API_ENDPOINT=$UMAMI_API_ENDPOINT +ENV S3_ENDPOINT=$S3_ENDPOINT +ENV S3_ACCESS_KEY=$S3_ACCESS_KEY +ENV S3_SECRET_KEY=$S3_SECRET_KEY +ENV S3_BUCKET=$S3_BUCKET +ENV S3_REGION=$S3_REGION +ENV S3_PREFIX=$S3_PREFIX ENV SKIP_RUNTIME_ENV_VALIDATION=true ENV CI=true diff --git a/apps/web/app/(payload)/admin/importMap.js b/apps/web/app/(payload)/admin/importMap.js index 829d6dd..5deabbc 100644 --- a/apps/web/app/(payload)/admin/importMap.js +++ b/apps/web/app/(payload)/admin/importMap.js @@ -32,6 +32,7 @@ import { default as default_2ebf44fdf8ebc607cf0de30cff485248 } from "@/src/paylo import { default as default_a1c6da8fb7dd9846a8b07123ff256d09 } from "@/src/payload/components/IconSelector"; import { ConvertInquiryButton as ConvertInquiryButton_09fd670bce023a947ab66e4eebea5168 } from "@/src/payload/components/ConvertInquiryButton"; import { AiAnalyzeButton as AiAnalyzeButton_51a6009c2b12d068d736ffd2b8182c71 } from "@/src/payload/components/AiAnalyzeButton"; +import { BulkMailButton as BulkMailButton_ebc54eabb8a07878581b0043bd687708 } from "@/src/payload/components/BulkMailButton"; import { GanttChartView as GanttChartView_0162b82db971e8f1e27fbdd0aaa2f1f4 } from "@/src/payload/views/GanttChart"; import { ChatWindowProvider as ChatWindowProvider_258e2d0901cb901e46c3eeed91676211 } from "@mintel/payload-ai/components/ChatWindow/index"; import { S3ClientUploadHandler as S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24 } from "@payloadcms/storage-s3/client"; @@ -106,6 +107,8 @@ export const importMap = { ConvertInquiryButton_09fd670bce023a947ab66e4eebea5168, "@/src/payload/components/AiAnalyzeButton#AiAnalyzeButton": AiAnalyzeButton_51a6009c2b12d068d736ffd2b8182c71, + "@/src/payload/components/BulkMailButton#BulkMailButton": + BulkMailButton_ebc54eabb8a07878581b0043bd687708, "@/src/payload/views/GanttChart#GanttChartView": GanttChartView_0162b82db971e8f1e27fbdd0aaa2f1f4, "@mintel/payload-ai/components/ChatWindow/index#ChatWindowProvider": diff --git a/apps/web/app/(site)/globals.css b/apps/web/app/(site)/globals.css index 0cc8d11..4a3ff14 100644 --- a/apps/web/app/(site)/globals.css +++ b/apps/web/app/(site)/globals.css @@ -24,19 +24,19 @@ } h1 { - @apply text-4xl md:text-8xl leading-[1.1] md:leading-[0.95] mb-6 md:mb-12; + @apply text-4xl md:text-6xl lg:text-8xl leading-[1.1] md:leading-[1] lg:leading-[0.95] mb-6 md:mb-8 lg:mb-12; } h2 { - @apply text-2xl md:text-6xl leading-tight mb-4 md:mb-8 mt-12 md:mt-16; + @apply text-2xl md:text-4xl lg:text-6xl leading-tight mb-4 md:mb-6 lg:mb-8 mt-12 lg:mt-16; } h3 { - @apply text-xl md:text-5xl leading-tight mb-3 md:mb-6 mt-8 md:mt-12; + @apply text-xl md:text-3xl lg:text-5xl leading-tight mb-3 md:mb-4 lg:mb-6 mt-8 lg:mt-12; } h4 { - @apply text-lg md:text-3xl leading-tight mb-3 md:mb-4 mt-6 md:mt-8; + @apply text-lg md:text-2xl lg:text-3xl leading-tight mb-3 lg:mb-4 mt-6 lg:mt-8; } p { @@ -44,7 +44,7 @@ } .lead { - @apply text-base md:text-2xl text-slate-600 mb-6 leading-relaxed; + @apply text-base md:text-xl lg:text-2xl text-slate-600 mb-6 leading-relaxed; font-weight: 400; } @@ -92,15 +92,15 @@ } .container { - @apply max-w-6xl mx-auto px-5 md:px-6 py-8 md:py-12; + @apply max-w-6xl mx-auto px-5 md:px-6 lg:px-8 py-8 md:py-10 lg:py-12; } .wide-container { - @apply max-w-7xl mx-auto px-5 md:px-6 py-10 md:py-16; + @apply max-w-7xl mx-auto px-5 md:px-6 lg:px-8 py-10 md:py-12 lg:py-16; } .narrow-container { - @apply max-w-4xl mx-auto px-5 md:px-6 py-6 md:py-10; + @apply max-w-4xl mx-auto px-5 md:px-6 lg:px-8 py-6 md:py-8 lg:py-10; } .highlighter-tag { diff --git a/apps/web/app/(site)/page.tsx b/apps/web/app/(site)/page.tsx index 288db31..8ef5edc 100644 --- a/apps/web/app/(site)/page.tsx +++ b/apps/web/app/(site)/page.tsx @@ -50,7 +50,7 @@ export default function LandingPage() { -
+
{[ { icon: , @@ -136,7 +136,7 @@ export default function LandingPage() { {/* Section 04: Target Group */}
-
+
@@ -215,8 +215,8 @@ export default function LandingPage() { }, ].map((service, i) => ( -
-
+
+
{/* Number + Binary */}
@@ -280,13 +280,13 @@ export default function LandingPage() {
-
-

+
+

Lassen Sie uns
starten.

-
+
Beschreiben Sie kurz Ihr Vorhaben. Ich melde mich{" "} diff --git a/apps/web/src/components/HeroSection.tsx b/apps/web/src/components/HeroSection.tsx index be3f69a..3e86432 100644 --- a/apps/web/src/components/HeroSection.tsx +++ b/apps/web/src/components/HeroSection.tsx @@ -47,7 +47,7 @@ export const HeroSection: React.FC = () => { initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} transition={{ duration: 1, delay: 0.2 }} - className="mb-4 md:mb-10 inline-flex items-center gap-3 md:gap-4 px-4 md:px-6 py-2 border border-slate-100 bg-white/40 backdrop-blur-sm rounded-full" + className="mb-4 md:mb-8 lg:mb-10 inline-flex items-center gap-3 md:gap-4 px-4 md:px-6 py-2 border border-slate-100 bg-white/40 backdrop-blur-sm rounded-full" >
@@ -59,7 +59,7 @@ export const HeroSection: React.FC = () => { {/* Headline */} -

+

Websites @@ -80,9 +80,9 @@ export const HeroSection: React.FC = () => { initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 1, delay: 0.8 }} - className="flex flex-col items-center gap-6 md:gap-12" + className="flex flex-col items-center gap-6 md:gap-8 lg:gap-12" > -

+

Ein Entwickler. Ein Ansprechpartner.{" "}
diff --git a/apps/web/src/components/Section.tsx b/apps/web/src/components/Section.tsx index 8aeffc5..01efa55 100644 --- a/apps/web/src/components/Section.tsx +++ b/apps/web/src/components/Section.tsx @@ -82,9 +82,9 @@ export const Section: React.FC = ({

{hasSidebar ? ( -
+
{/* Sidebar: Number & Title */} -
+
{number && ( @@ -124,7 +124,7 @@ export const Section: React.FC = ({
{/* Main Content */} -
{children}
+
{children}
) : (
{children}
diff --git a/apps/web/src/lib/env.ts b/apps/web/src/lib/env.ts index 74f3532..0d83d0f 100644 --- a/apps/web/src/lib/env.ts +++ b/apps/web/src/lib/env.ts @@ -8,8 +8,8 @@ const envExtension = { // Mail Configuration MAIL_HOST: z.string().optional(), MAIL_PORT: z.coerce.number().optional().default(587), - MAIL_USER: z.string().optional(), - MAIL_PASS: z.string().optional(), + MAIL_USERNAME: z.string().optional(), + MAIL_PASSWORD: z.string().optional(), MAIL_FROM: z.string().optional().default("marc@mintel.me"), MAIL_RECIPIENTS: z.string().optional().default("marc@mintel.me"), @@ -21,6 +21,14 @@ const envExtension = { .optional() .default("https://analytics.infra.mintel.me"), + // S3 Storage (Required for importMap at build-time) + S3_ENDPOINT: z.string().optional(), + S3_ACCESS_KEY: z.string().optional(), + S3_SECRET_KEY: z.string().optional(), + S3_BUCKET: z.string().optional(), + S3_REGION: z.string().optional(), + S3_PREFIX: z.string().optional(), + // Error Tracking SENTRY_DSN: z.string().optional(), }; diff --git a/apps/web/src/lib/mail/mailer.ts b/apps/web/src/lib/mail/mailer.ts index 3e09033..50440a2 100644 --- a/apps/web/src/lib/mail/mailer.ts +++ b/apps/web/src/lib/mail/mailer.ts @@ -24,8 +24,8 @@ function getTransporter() { port: env.MAIL_PORT, secure: env.MAIL_PORT === 465, auth: { - user: env.MAIL_USER, - pass: env.MAIL_PASS, + user: env.MAIL_USERNAME, + pass: env.MAIL_PASSWORD, }, }); diff --git a/apps/web/test-env.ts b/apps/web/test-env.ts new file mode 100644 index 0000000..6f310f2 --- /dev/null +++ b/apps/web/test-env.ts @@ -0,0 +1,18 @@ +import { z } from "zod"; +import { validateMintelEnv } from "@mintel/next-utils"; + +const envExtension = { + SENTRY_DSN: z.string().url().nullish().or(z.literal("")), +}; + +process.env.SENTRY_DSN = " "; +console.log("Empty Space:"); +try { + validateMintelEnv(envExtension); +} catch (e) {} + +process.env.SENTRY_DSN = "\n"; +console.log("Newline:"); +try { + validateMintelEnv(envExtension); +} catch (e) {}