Compare commits
@@ -1,11 +1,6 @@
|
|||||||
stages:
|
stages:
|
||||||
- Build
|
- Build
|
||||||
|
|
||||||
variables:
|
|
||||||
DOCKER_HOST: tcp://docker:2376
|
|
||||||
DOCKER_TLS_VERIFY: 1
|
|
||||||
DOCKER_CERT_PATH: /certs/client
|
|
||||||
|
|
||||||
"Build Docker":
|
"Build Docker":
|
||||||
stage: Build
|
stage: Build
|
||||||
image: docker:24.0.5
|
image: docker:24.0.5
|
||||||
|
|||||||
+5
-5
@@ -10,14 +10,14 @@ FROM node:alpine AS builder
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=deps /app/node_modules ./node_modules
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
COPY . .
|
COPY . .
|
||||||
ENV NEXT_TELEMETRY_DISABLED 1
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# 3. Production image (Slimmad!)
|
# 3. Production image (Slimmad!)
|
||||||
FROM node:alpine AS runner
|
FROM node:alpine AS runner
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV NODE_ENV production
|
ENV NODE_ENV=production
|
||||||
ENV NEXT_TELEMETRY_DISABLED 1
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
|
||||||
RUN mkdir -p data
|
RUN mkdir -p data
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ COPY --from=builder /app/.next/standalone ./
|
|||||||
COPY --from=builder /app/.next/static ./.next/static
|
COPY --from=builder /app/.next/static ./.next/static
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
ENV PORT 3000
|
ENV PORT=3000
|
||||||
ENV HOSTNAME "0.0.0.0"
|
ENV HOSTNAME="0.0.0.0"
|
||||||
|
|
||||||
CMD ["node", "server.js"]
|
CMD ["node", "server.js"]
|
||||||
@@ -9,7 +9,7 @@ import Footer from '../components/Footer';
|
|||||||
import Header from '../components/Header';
|
import Header from '../components/Header';
|
||||||
import BeachRegistrationForm from './BeachRegistrationForm';
|
import BeachRegistrationForm from './BeachRegistrationForm';
|
||||||
|
|
||||||
export default function BeachClientPage({ config }: { config: any }) {
|
export default function BeachClientPage({ config, turnstileSiteKey }: { config: any, turnstileSiteKey: string }) {
|
||||||
const [timeInfo, setTimeInfo] = useState({
|
const [timeInfo, setTimeInfo] = useState({
|
||||||
dateStr: 'Laddar...',
|
dateStr: 'Laddar...',
|
||||||
matchStr: 'Laddar...',
|
matchStr: 'Laddar...',
|
||||||
@@ -141,7 +141,7 @@ export default function BeachClientPage({ config }: { config: any }) {
|
|||||||
<h4 className="font-beachday text-2xl uppercase tracking-[0.05em] text-black">Klasser</h4>
|
<h4 className="font-beachday text-2xl uppercase tracking-[0.05em] text-black">Klasser</h4>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-gray-700 text-sm space-y-3">
|
<div className="text-gray-700 text-sm space-y-3">
|
||||||
<p className="leading-snug">Turneringen kan delas upp i tre klasser beroende på antal anmälda lag och nivå:</p>
|
<p className="leading-snug">Turneringen kommer att delas upp i flera olika klasser beroende på antal anmälda lag och dess nivå:</p>
|
||||||
<div className="flex gap-2 flex-wrap">
|
<div className="flex gap-2 flex-wrap">
|
||||||
{classesData.map((c: any, i: number) => (
|
{classesData.map((c: any, i: number) => (
|
||||||
<span
|
<span
|
||||||
@@ -153,7 +153,7 @@ export default function BeachClientPage({ config }: { config: any }) {
|
|||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<p className="italic text-xs text-gray-500">Gör en gissning på er nivå i anmälan – skriv gärna om ni är osäkra.</p>
|
<p className="italic text-xs text-gray-500">Gör en gissning på er nivå i anmälan – skriv gärna något extra om ni är osäkra. Vi meddelar om det skulle bli ändringar.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ export default function BeachClientPage({ config }: { config: any }) {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Rendera formuläret endast om anmälan är öppen */}
|
{/* Rendera formuläret endast om anmälan är öppen */}
|
||||||
{!timeInfo.isClosed && <BeachRegistrationForm config={config} />}
|
{!timeInfo.isClosed && <BeachRegistrationForm config={config} turnstileSiteKey={turnstileSiteKey} />}
|
||||||
|
|
||||||
<section className="w-full flex justify-center px-4 mt-10 mb-20">
|
<section className="w-full flex justify-center px-4 mt-10 mb-20">
|
||||||
<div className="bg-linear-to-br from-[#39979f] to-[#62b8bc] p-10 md:p-12 rounded-[40px] shadow-2xl w-full max-w-2xl text-center transform transition-transform duration-500 border border-blue-400/20 relative overflow-hidden group">
|
<div className="bg-linear-to-br from-[#39979f] to-[#62b8bc] p-10 md:p-12 rounded-[40px] shadow-2xl w-full max-w-2xl text-center transform transition-transform duration-500 border border-blue-400/20 relative overflow-hidden group">
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import React, { useRef, useActionState, useEffect } from 'react';
|
|||||||
import { FaUser, FaEnvelope, FaPhone, FaUsers, FaTrophy, FaCheckCircle, FaExclamationTriangle } from "react-icons/fa";
|
import { FaUser, FaEnvelope, FaPhone, FaUsers, FaTrophy, FaCheckCircle, FaExclamationTriangle } from "react-icons/fa";
|
||||||
import { submitRegistration } from './actions';
|
import { submitRegistration } from './actions';
|
||||||
|
|
||||||
export default function BeachRegistrationForm({ config }: { config: any }) {
|
export default function BeachRegistrationForm({ config, turnstileSiteKey }: { config: any, turnstileSiteKey: string }) {
|
||||||
const [state, formAction, isPending] = useActionState(submitRegistration, null);
|
const [state, formAction, isPending] = useActionState(submitRegistration, null);
|
||||||
const formRef = useRef<HTMLFormElement>(null);
|
const formRef = useRef<HTMLFormElement>(null);
|
||||||
const turnstileRef = useRef<TurnstileInstance>(null);
|
const turnstileRef = useRef<TurnstileInstance>(null);
|
||||||
@@ -130,13 +130,7 @@ export default function BeachRegistrationForm({ config }: { config: any }) {
|
|||||||
|
|
||||||
<input type="text" name="website" className="hidden" tabIndex={-1} />
|
<input type="text" name="website" className="hidden" tabIndex={-1} />
|
||||||
|
|
||||||
<div className="flex justify-center py-2">
|
<div className="flex justify-center py-2"><Turnstile ref={turnstileRef} siteKey={turnstileSiteKey} options={{ theme: 'light' }}/></div>
|
||||||
<Turnstile
|
|
||||||
ref={turnstileRef}
|
|
||||||
siteKey={process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY || ''}
|
|
||||||
options={{ theme: 'light' }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{state && (
|
{state && (
|
||||||
<div className={`flex items-center gap-3 p-5 rounded-2xl font-bold transition-all ${state.success ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-700'}`}>
|
<div className={`flex items-center gap-3 p-5 rounded-2xl font-bold transition-all ${state.success ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-700'}`}>
|
||||||
|
|||||||
+7
-2
@@ -2,11 +2,16 @@
|
|||||||
import { getConfig } from '../lib/config';
|
import { getConfig } from '../lib/config';
|
||||||
import BeachClientPage from './BeachClientPage';
|
import BeachClientPage from './BeachClientPage';
|
||||||
|
|
||||||
|
export const dynamic = 'force-dynamic';
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
title: 'Beachturnering',
|
title: 'Beachturnering',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default async function BeachPage() {
|
export default async function BeachPage() {
|
||||||
const config = await getConfig();
|
const config = await getConfig();
|
||||||
return <BeachClientPage config={config} />;
|
|
||||||
}
|
const turnstileSiteKey = process.env.TURNSTILE_SITE_KEY || '';
|
||||||
|
|
||||||
|
return <BeachClientPage config={config} turnstileSiteKey={turnstileSiteKey} />;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user