From 5bfbb3b88c72343f2c941eb88dc4b2ec0002d324 Mon Sep 17 00:00:00 2001 From: Atridad Lahiji Date: Wed, 22 Jan 2025 22:38:19 -0600 Subject: [PATCH] Try building --- .env.example | 6 ++ Dockerfile | 44 ++++++++++ docker-compose.yml | 15 ++++ package.json | 1 + pnpm-lock.yaml | 9 ++ src/components/ContactForm.tsx | 140 +++++++++++++++++++++++++++++ src/components/Footer.astro | 8 +- src/components/Header.astro | 50 +++++++---- src/config/site.ts | 106 ++++++++++++++++++++++ src/layouts/Layout.astro | 14 +-- src/pages/api/contact.ts | 58 ++++++++++++ src/pages/contact.astro | 25 ++++++ src/pages/index.astro | 155 ++++++++++++++++----------------- src/pages/services.astro | 68 +++++++++++++++ tailwind.config.mjs | 2 +- 15 files changed, 597 insertions(+), 104 deletions(-) create mode 100644 .env.example create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 src/components/ContactForm.tsx create mode 100644 src/config/site.ts create mode 100644 src/pages/api/contact.ts create mode 100644 src/pages/contact.astro create mode 100644 src/pages/services.astro diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..53a2272 --- /dev/null +++ b/.env.example @@ -0,0 +1,6 @@ +SMTP_HOST= +SMTP_PORT=587 +SMTP_USER= +SMTP_PASS= +FROM_EMAIL= +TO_EMAIL= diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7a4cd9b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,44 @@ +# Build stage +FROM node:20-alpine AS builder + +# Install pnpm +RUN corepack enable && corepack prepare pnpm@latest --activate + +WORKDIR /app + +# Copy package files +COPY package.json pnpm-lock.yaml ./ + +# Install dependencies +RUN pnpm install --frozen-lockfile + +# Copy source code +COPY . . + +# Build the application +RUN pnpm run build + +# Production stage +FROM node:20-alpine + +# Install pnpm +RUN corepack enable && corepack prepare pnpm@latest --activate + +WORKDIR /app + +# Copy built assets and necessary files +COPY --from=builder /app/dist ./dist +COPY --from=builder /app/package.json ./package.json +COPY --from=builder /app/pnpm-lock.yaml ./pnpm-lock.yaml + +# Install only production dependencies +RUN pnpm install --prod --frozen-lockfile + +# Copy environment variables if needed +COPY .env.production ./.env + +# Expose the port your app runs on +EXPOSE 3000 + +# Start the application +CMD ["node", "./dist/server/entry.mjs"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d632efe --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +services: + app: + image: ${IMAGE} + ports: + - "${APP_PORT}:3000" + environment: + - HOST=0.0.0.0 + - PORT=3000 + - SMTP_HOST=${SMTP_HOST} + - SMTP_PORT=${SMTP_PORT} + - SMTP_USER=${SMTP_USER} + - SMTP_PASS=${SMTP_PASS} + - FROM_EMAIL=${FROM_EMAIL} + - TO_EMAIL=${TO_EMAIL} + restart: unless-stopped diff --git a/package.json b/package.json index 7114485..a9e5cd9 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@astrojs/solid-js": "^5.0.4", "@astrojs/tailwind": "^5.1.5", "astro": "^5.1.8", + "nodemailer": "^6.9.16", "solid-js": "^1.9.4", "tailwindcss": "^3.4.17" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ed828e8..f3bb400 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: astro: specifier: ^5.1.8 version: 5.1.8(jiti@1.21.7)(rollup@4.31.0)(typescript@5.7.3)(yaml@2.7.0) + nodemailer: + specifier: ^6.9.16 + version: 6.9.16 solid-js: specifier: ^1.9.4 version: 1.9.4 @@ -1351,6 +1354,10 @@ packages: node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + nodemailer@6.9.16: + resolution: {integrity: sha512-psAuZdTIRN08HKVd/E8ObdV6NO7NTBY3KsC30F7M4H1OnmLCUNaS56FpYxyb26zWLSyYF9Ozch9KYHhHegsiOQ==} + engines: {node: '>=6.0.0'} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -3552,6 +3559,8 @@ snapshots: node-releases@2.0.19: {} + nodemailer@6.9.16: {} + normalize-path@3.0.0: {} normalize-range@0.1.2: {} diff --git a/src/components/ContactForm.tsx b/src/components/ContactForm.tsx new file mode 100644 index 0000000..86a9756 --- /dev/null +++ b/src/components/ContactForm.tsx @@ -0,0 +1,140 @@ +import { createSignal, type Component } from "solid-js"; +import { Show } from "solid-js/web"; + +const ContactForm: Component = () => { + const [email, setEmail] = createSignal(""); + const [message, setMessage] = createSignal(""); + const [status, setStatus] = createSignal< + "idle" | "sending" | "success" | "error" + >("idle"); + const [errorMessage, setErrorMessage] = createSignal(""); + + const handleSubmit = async (e: Event) => { + e.preventDefault(); + setStatus("sending"); + setErrorMessage(""); + + try { + const response = await fetch("/api/contact", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email: email(), + message: message(), + }), + }); + + if (!response.ok) { + throw new Error("Failed to send message"); + } + + setStatus("success"); + setEmail(""); + setMessage(""); + + // Reset success status after 3 seconds + setTimeout(() => setStatus("idle"), 3000); + } catch (error) { + setStatus("error"); + setErrorMessage( + error instanceof Error ? error.message : "Failed to send message", + ); + } + }; + + return ( +
+
+ + setEmail(e.currentTarget.value)} + disabled={status() === "sending"} + /> +
+ +
+ +