commit 1e5f2bc38a39108dfc8bc22eed7d421dea2b5f0a Author: dm Date: Thu Nov 20 21:22:37 2025 +0100 Szablon witryny, docker i workflow gitea diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..1eb747e --- /dev/null +++ b/.env.example @@ -0,0 +1,11 @@ +# Public URL of the website +PUBLIC_SITE_URL=https://www.fuz.dariuszm.eu + +# Google Maps +PUBLIC_GOOGLE_MAPS_KEY= + +# Contact form API +FORMS_ENDPOINT= + +# Astro SSR +NODE_ENV=production diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..1dc0a08 --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,27 @@ +name: Deploy FUZ 2.0 to Contabo + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: contabo-runner + + steps: + - name: Pull latest code + run: | + cd /opt/fuz-site + git reset --hard HEAD + git pull + + - name: Build image + run: | + cd /opt/fuz-site + docker compose -f docker-compose.prod.yml build + + - name: Restart service + run: | + cd /opt/fuz-site + docker compose -f docker-compose.prod.yml up -d diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2acf0d --- /dev/null +++ b/.gitignore @@ -0,0 +1,44 @@ + +# Node +node_modules/ +npm-debug.log* +yarn-debug.log* +pnpm-debug.log* +package-lock.json +pnpm-lock.yaml + +# Astro +dist/ +.astro/ +.build/ + +# Logs +*.log +logs/ + +# Env +.env +.env.* +!.env.example + +# OS +.DS_Store +Thumbs.db + +# Editor +.vscode/ +.idea/ + +# Docker +docker-data/ +docker-cache/ + +# Temp +tmp/ +temp/ +*.tmp + +# Public generated +public/**/*.avif +public/**/*.webp +public/og/*.txt diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..76a7d2a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +# ============================ +# 1) BUILD STAGE +# ============================ +FROM node:18-alpine AS builder + +WORKDIR /app + +COPY package*.json ./ +RUN npm install + +COPY . . +RUN npm run build + +# ============================ +# 2) RUNTIME STAGE (alpine) +# ============================ +FROM node:18-alpine + +WORKDIR /app + +COPY --from=builder /app /app + +ENV NODE_ENV=production + +EXPOSE 3000 + +CMD ["node", "dist/server/entry.mjs"] diff --git a/astro.config.mjs b/astro.config.mjs new file mode 100644 index 0000000..f909cf2 --- /dev/null +++ b/astro.config.mjs @@ -0,0 +1,12 @@ +import { defineConfig } from 'astro/config'; +import tailwind from '@astrojs/tailwind'; + +export default defineConfig({ + srcDir: 'src', + output: 'server', + integrations: [ + tailwind({ + applyBaseStyles: true + }) + ] +}); diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..ee8d12f --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,19 @@ +version: "3.9" + +services: + fuz-site: + build: + context: /opt/fuz-site + dockerfile: Dockerfile + container_name: fuz-site + restart: unless-stopped + env_file: + - .env + ports: + - "4000:3000" + networks: + - n8n_default + +networks: + n8n_default: + external: true diff --git a/package.json b/package.json new file mode 100644 index 0000000..351dade --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "fuz20", + "version": "1.0.0", + "private": true, + "scripts": { + "dev": "astro dev", + "build": "astro build", + "preview": "astro preview" + }, + "dependencies": { + "astro": "^4.0.0", + "js-yaml": "^4.1.0" + }, + "devDependencies": { + "@astrojs/tailwind": "^5.0.0", + "tailwindcss": "^3.4.0", + "autoprefixer": "^10.4.0", + "postcss": "^8.4.0" + } +} diff --git a/postcss.config.cjs b/postcss.config.cjs new file mode 100644 index 0000000..5cbc2c7 --- /dev/null +++ b/postcss.config.cjs @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +}; diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..c10a889 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,4 @@ + + + F + diff --git a/src/components/hero/Hero.astro b/src/components/hero/Hero.astro new file mode 100644 index 0000000..2e7e93d --- /dev/null +++ b/src/components/hero/Hero.astro @@ -0,0 +1,63 @@ +--- +const { + title = [], + subtitle = [], + description, + imageUrl, + ctas = [] +} = Astro.props; +--- + +
+
+
+ {Array.isArray(title) ? ( +

+ {title.map((line) => ( + {line} + ))} +

+ ) : ( +

{title}

+ )} + + {Array.isArray(subtitle) && subtitle.length > 0 && ( +
+ {subtitle.map((line) => ( +

{line}

+ ))} +
+ )} + + {description && ( +

+ {description} +

+ )} + + {ctas.length > 0 && ( +
+ {ctas.map((cta) => ( + + {cta.label} + + ))} +
+ )} +
+ + {imageUrl && ( +
+ +
+ )} +
+
diff --git a/src/components/layout/Footer.astro b/src/components/layout/Footer.astro new file mode 100644 index 0000000..ebf4f9f --- /dev/null +++ b/src/components/layout/Footer.astro @@ -0,0 +1,10 @@ + diff --git a/src/components/layout/Header.astro b/src/components/layout/Header.astro new file mode 100644 index 0000000..8642442 --- /dev/null +++ b/src/components/layout/Header.astro @@ -0,0 +1,29 @@ +--- +const nav = [ + { href: "/", label: "Strona główna" }, + { href: "/internet", label: "Internet" }, + { href: "/telewizja", label: "Telewizja" }, + { href: "/internet-telewizja", label: "Internet + TV" }, + { href: "/mapa-zasiegu", label: "Mapa zasięgu" }, + { href: "/kontakt", label: "Kontakt" } +]; +--- + +
+
+ + + F + + FUZ + + + +
+
diff --git a/src/components/ui/Button.astro b/src/components/ui/Button.astro new file mode 100644 index 0000000..079d3df --- /dev/null +++ b/src/components/ui/Button.astro @@ -0,0 +1,21 @@ +--- +const { href, variant = "primary" } = Astro.props; + +const base = + "inline-flex items-center justify-center rounded-full px-4 py-2 text-sm font-medium transition"; +const variants = { + primary: "bg-sky-600 text-white hover:bg-sky-700 dark:bg-sky-500 dark:hover:bg-sky-400", + secondary: "bg-slate-100 text-slate-900 hover:bg-slate-200 dark:bg-slate-800 dark:text-slate-100" +}; +const classes = `${base} ${variants[variant] ?? variants.primary}`; +--- + +{href ? ( + + + +) : ( + +)} diff --git a/src/components/ui/Toast.astro b/src/components/ui/Toast.astro new file mode 100644 index 0000000..524b098 --- /dev/null +++ b/src/components/ui/Toast.astro @@ -0,0 +1,15 @@ +--- +const { message, type = "success" } = Astro.props; + +const base = "fixed right-4 top-20 z-50 rounded-xl px-4 py-3 text-sm shadow-lg border backdrop-blur"; +const variants = { + success: "bg-emerald-50/90 border-emerald-200 text-emerald-900 dark:bg-emerald-900/70 dark:border-emerald-700 dark:text-emerald-50", + error: "bg-rose-50/90 border-rose-200 text-rose-900 dark:bg-rose-900/70 dark:border-rose-700 dark:text-rose-50", + info: "bg-sky-50/90 border-sky-200 text-sky-900 dark:bg-sky-900/70 dark:border-sky-700 dark:text-sky-50" +}; +const classes = `${base} ${variants[type] ?? variants.success}`; +--- + +
+ {message} +
diff --git a/src/content/home/hero.yaml b/src/content/home/hero.yaml new file mode 100644 index 0000000..e698fc9 --- /dev/null +++ b/src/content/home/hero.yaml @@ -0,0 +1,13 @@ +title: + - "Dlaczego FUZ?" +subtitle: + - "Lokalny operator – znamy Twoją okolicę" + - "Realny serwis, szybkie wsparcie" + - "Stabilna infrastruktura światłowodowa i radiowa" +description: "Internet i telewizja od ludzi, którzy naprawdę są na miejscu. Bez infolinii z końca świata." +imageUrl: "/images/hero/fiber-example.jpg" +ctas: + - label: "Sprawdź dostępność" + href: "/mapa-zasiegu" + - label: "Zobacz ofertę" + href: "/oferta" diff --git a/src/content/seo/home.yaml b/src/content/seo/home.yaml new file mode 100644 index 0000000..484ab00 --- /dev/null +++ b/src/content/seo/home.yaml @@ -0,0 +1,16 @@ +title: "FUZ – Internet i telewizja w Twojej okolicy" +description: "Lokalny operator internetu i telewizji. Nowoczesny światłowód i radio, realny serwis i szybkie wsparcie." +canonical: "/" +image: "/og/fuz-home.png" +keywords: + - internet + - światłowód + - telewizja + - lokalny operator +schema: + "@context": "https://schema.org" + "@type": "Organization" + name: "FUZ" + url: "https://www.fuz.pl" + sameAs: + - "https://www.facebook.com" diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 0000000..9bc5cb4 --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1 @@ +/// \ No newline at end of file diff --git a/src/layouts/BaseHead.astro b/src/layouts/BaseHead.astro new file mode 100644 index 0000000..be02f6e --- /dev/null +++ b/src/layouts/BaseHead.astro @@ -0,0 +1,43 @@ +--- +const { seo } = Astro.props; + +const { + title = "FUZ", + description = "Lokalny operator internetu i telewizji.", + canonical = "/", + image = "/og/default.png", + keywords = [], + schema = {} +} = seo ?? {}; +--- + + + + + + {title} + + {keywords.length > 0 && ( + + )} + + + + + + + + + + + + + + {Object.keys(schema).length > 0 && ( + + )} + + + diff --git a/src/layouts/DefaultLayout.astro b/src/layouts/DefaultLayout.astro new file mode 100644 index 0000000..d3c1719 --- /dev/null +++ b/src/layouts/DefaultLayout.astro @@ -0,0 +1,22 @@ +--- +import "../styles/base.css"; +import BaseHead from "./BaseHead.astro"; +import Header from "../components/layout/Header.astro"; +import Footer from "../components/layout/Footer.astro"; + +const { seo } = Astro.props; +--- + + + + + +
+ +
+ +
+ +