Web UI setup

This commit is contained in:
nemunaire 2025-10-17 17:18:37 +07:00
commit 0889dce85b
19 changed files with 6026 additions and 2 deletions

View file

@ -1,5 +1,17 @@
# Multi-stage Dockerfile for happyDeliver with integrated MTA
# Stage 1: Build the Go application
# Stage 1: Build the Svelte application
FROM node:22-alpine AS nodebuild
WORKDIR /build
COPY api/ api/
COPY web/ web/
RUN yarn --cwd web install && \
yarn --cwd web run generate:api && \
yarn --cwd web --offline build
# Stage 2: Build the Go application
FROM golang:1-alpine AS builder
WORKDIR /build
@ -13,11 +25,12 @@ RUN go mod download
# Copy source code
COPY . .
COPY --from=nodebuild /build/web/build/ ./web/build/
# Build the application
RUN CGO_ENABLED=1 GOOS=linux go build -a -installsuffix cgo -ldflags="-w -s" -o happyDeliver ./cmd/happyDeliver
# Stage 2: Runtime image with Postfix and all filters
# Stage 3: Runtime image with Postfix and all filters
FROM alpine:3
# Install all required packages

View file

@ -34,6 +34,7 @@ import (
"git.happydns.org/happyDeliver/internal/config"
"git.happydns.org/happyDeliver/internal/receiver"
"git.happydns.org/happyDeliver/internal/storage"
"git.happydns.org/happyDeliver/web"
)
const version = "0.1.0-dev"
@ -89,6 +90,7 @@ func runServer(cfg *config.Config) {
// Register API routes
apiGroup := router.Group("/api")
api.RegisterHandlers(apiGroup, handler)
web.DeclareRoutes(cfg, router)
// Start server
log.Printf("Starting API server on %s", cfg.Bind)

26
web/.gitignore vendored Normal file
View file

@ -0,0 +1,26 @@
node_modules
# Output
.output
.vercel
.netlify
.wrangler
/.svelte-kit
/build
# OS
.DS_Store
Thumbs.db
# Env
.env
.env.*
!.env.example
!.env.test
# Vite
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
# OpenAPI
src/lib/api

1
web/.npmrc Normal file
View file

@ -0,0 +1 @@
engine-strict=true

9
web/.prettierignore Normal file
View file

@ -0,0 +1,9 @@
# Package Managers
package-lock.json
pnpm-lock.yaml
yarn.lock
bun.lock
bun.lockb
# Miscellaneous
/static/

13
web/.prettierrc Normal file
View file

@ -0,0 +1,13 @@
{
"tabWidth": 4,
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"overrides": [
{
"files": "*.svelte",
"options": {
"parser": "svelte"
}
}
]
}

43
web/assets.go Normal file
View file

@ -0,0 +1,43 @@
// This file is part of the happyDeliver (R) project.
// Copyright (c) 2025 happyDomain
// Authors: Pierre-Olivier Mercier, et al.
//
// This program is offered under a commercial and under the AGPL license.
// For commercial licensing, contact us at <contact@happydomain.org>.
//
// For AGPL licensing:
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package web
import (
"embed"
"io/fs"
"log"
"net/http"
)
//go:embed all:build
var _assets embed.FS
var Assets http.FileSystem
func init() {
sub, err := fs.Sub(_assets, "build")
if err != nil {
log.Fatal("Unable to cd to build/ directory:", err)
}
Assets = http.FS(sub)
}

41
web/eslint.config.js Normal file
View file

@ -0,0 +1,41 @@
import prettier from "eslint-config-prettier";
import { fileURLToPath } from "node:url";
import { includeIgnoreFile } from "@eslint/compat";
import js from "@eslint/js";
import svelte from "eslint-plugin-svelte";
import { defineConfig } from "eslint/config";
import globals from "globals";
import ts from "typescript-eslint";
import svelteConfig from "./svelte.config.js";
const gitignorePath = fileURLToPath(new URL("./.gitignore", import.meta.url));
export default defineConfig(
includeIgnoreFile(gitignorePath),
js.configs.recommended,
...ts.configs.recommended,
...svelte.configs.recommended,
prettier,
...svelte.configs.prettier,
{
languageOptions: {
globals: { ...globals.browser, ...globals.node },
},
rules: {
// typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects.
// see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
"no-undef": "off",