csv delimiter is now ; and dockerfile was added

This commit is contained in:
2025-12-01 09:36:48 +00:00
parent 1e5fd35659
commit c2429bcc4a
8 changed files with 178 additions and 70 deletions

41
Dockerfile Normal file
View File

@@ -0,0 +1,41 @@
# Build stage
FROM golang:1.24-alpine AS builder
# Set working directory
WORKDIR /app
# Copy go mod files first for better caching
COPY go.mod go.sum ./
# Download dependencies
RUN go mod download
# Copy source code
COPY . .
# Build the application
# Static binary without CGO
RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-w -s' -o meshi .
# Runtime stage
FROM alpine:latest AS runtime
# Create non-root user for security
RUN addgroup -g 1000 -S appgroup && \
adduser -u 1000 -S appuser -G appgroup
# Set working directory
WORKDIR /app
# Copy binary from builder stage
COPY --from=builder /app/meshi .
# Create data directory and set permissions
RUN mkdir -p /app/data && \
chown -R appuser:appgroup /app
# Switch to non-root user
USER appuser
# Run the application
CMD ["./meshi"]

View File

@@ -30,46 +30,77 @@
} }
:root { :root {
--radius: 0.65rem; --background: oklch(1 0 0);
--background: oklch(1 0 0); --foreground: oklch(0.141 0.005 285.823);
--foreground: oklch(0.145 0 0); --card: oklch(1 0 0);
--card: oklch(1 0 0); --card-foreground: oklch(0.141 0.005 285.823);
--card-foreground: oklch(0.145 0 0); --popover: oklch(1 0 0);
--popover: oklch(1 0 0); --popover-foreground: oklch(0.141 0.005 285.823);
--popover-foreground: oklch(0.145 0 0); --primary: oklch(54.6% 0.245 262.881);
--primary: oklch(0.205 0 0); --primary-foreground: oklch(0.97 0.014 254.604);
--primary-foreground: oklch(0.985 0 0); --secondary: oklch(0.967 0.001 286.375);
--secondary: oklch(0.97 0 0); --secondary-foreground: oklch(0.21 0.006 285.885);
--secondary-foreground: oklch(0.205 0 0); --muted: oklch(0.967 0.001 286.375);
--muted: oklch(0.97 0 0); --muted-foreground: oklch(0.552 0.016 285.938);
--muted-foreground: oklch(0.556 0 0); --accent: oklch(0.967 0.001 286.375);
--accent: oklch(0.97 0 0); --accent-foreground: oklch(0.21 0.006 285.885);
--accent-foreground: oklch(0.205 0 0); --destructive: oklch(0.577 0.245 27.325);
--destructive: oklch(0.577 0.245 27.325); --border: oklch(0.92 0.004 286.32);
--border: oklch(0.922 0 0); --input: oklch(0.92 0.004 286.32);
--input: oklch(0.922 0 0); --ring: oklch(0.623 0.214 259.815);
--ring: oklch(0.708 0 0); --radius: 0.65rem;
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.141 0.005 285.823);
--sidebar-primary: oklch(54.6% 0.245 262.881);
--sidebar-primary-foreground: oklch(0.97 0.014 254.604);
--sidebar-accent: oklch(0.94 0.001 286.375);
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
--sidebar-border: oklch(0.92 0.004 286.32);
--sidebar-ring: oklch(0.623 0.214 259.815);
--selection: oklch(0.141 0.005 285.823);
--selection-foreground: oklch(1 0 0);
} }
.dark { .dark {
--background: oklch(0.145 0 0); --background: oklch(0.141 0.005 285.823);
--foreground: oklch(0.985 0 0); --foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0); --card: oklch(0.21 0.006 285.885);
--card-foreground: oklch(0.985 0 0); --card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0); --popover: oklch(0.21 0.006 285.885);
--popover-foreground: oklch(0.985 0 0); --popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0); --primary: oklch(62.3% 0.214 259.815);
--primary-foreground: oklch(0.205 0 0); --primary-foreground: oklch(97% 0.014 254.604);
--secondary: oklch(0.269 0 0); --secondary: oklch(0.274 0.006 286.033);
--secondary-foreground: oklch(0.985 0 0); --secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0); --muted: oklch(0.274 0.006 286.033);
--muted-foreground: oklch(0.708 0 0); --muted-foreground: oklch(0.705 0.015 286.067);
--accent: oklch(0.269 0 0); --accent: oklch(0.274 0.006 286.033);
--accent-foreground: oklch(0.985 0 0); --accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216); --destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%); --border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%); --input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0); --ring: oklch(0.488 0.243 264.376);
--radius: 0.65rem;
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.21 0.006 285.885);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(62.3% 0.214 259.815);
--sidebar-primary-foreground: oklch(97% 0.014 254.604);
--sidebar-accent: oklch(0.3 0.006 286.033);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.488 0.243 264.376);
--selection: oklch(0.92 0.004 286.32);
--selection-foreground: oklch(0.21 0.006 285.885);
} }
@layer base { @layer base {

View File

@@ -176,6 +176,9 @@
.mt-4 { .mt-4 {
margin-top: calc(var(--spacing) * 4); margin-top: calc(var(--spacing) * 4);
} }
.flex {
display: flex;
}
.table { .table {
display: table; display: table;
} }
@@ -297,45 +300,76 @@
} }
} }
:root { :root {
--radius: 0.65rem;
--background: oklch(1 0 0); --background: oklch(1 0 0);
--foreground: oklch(0.145 0 0); --foreground: oklch(0.141 0.005 285.823);
--card: oklch(1 0 0); --card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0); --card-foreground: oklch(0.141 0.005 285.823);
--popover: oklch(1 0 0); --popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0); --popover-foreground: oklch(0.141 0.005 285.823);
--primary: oklch(0.205 0 0); --primary: oklch(54.6% 0.245 262.881);
--primary-foreground: oklch(0.985 0 0); --primary-foreground: oklch(0.97 0.014 254.604);
--secondary: oklch(0.97 0 0); --secondary: oklch(0.967 0.001 286.375);
--secondary-foreground: oklch(0.205 0 0); --secondary-foreground: oklch(0.21 0.006 285.885);
--muted: oklch(0.97 0 0); --muted: oklch(0.967 0.001 286.375);
--muted-foreground: oklch(0.556 0 0); --muted-foreground: oklch(0.552 0.016 285.938);
--accent: oklch(0.97 0 0); --accent: oklch(0.967 0.001 286.375);
--accent-foreground: oklch(0.205 0 0); --accent-foreground: oklch(0.21 0.006 285.885);
--destructive: oklch(0.577 0.245 27.325); --destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0); --border: oklch(0.92 0.004 286.32);
--input: oklch(0.922 0 0); --input: oklch(0.92 0.004 286.32);
--ring: oklch(0.708 0 0); --ring: oklch(0.623 0.214 259.815);
--radius: 0.65rem;
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.141 0.005 285.823);
--sidebar-primary: oklch(54.6% 0.245 262.881);
--sidebar-primary-foreground: oklch(0.97 0.014 254.604);
--sidebar-accent: oklch(0.94 0.001 286.375);
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
--sidebar-border: oklch(0.92 0.004 286.32);
--sidebar-ring: oklch(0.623 0.214 259.815);
--selection: oklch(0.141 0.005 285.823);
--selection-foreground: oklch(1 0 0);
} }
.dark { .dark {
--background: oklch(0.145 0 0); --background: oklch(0.141 0.005 285.823);
--foreground: oklch(0.985 0 0); --foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0); --card: oklch(0.21 0.006 285.885);
--card-foreground: oklch(0.985 0 0); --card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0); --popover: oklch(0.21 0.006 285.885);
--popover-foreground: oklch(0.985 0 0); --popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0); --primary: oklch(62.3% 0.214 259.815);
--primary-foreground: oklch(0.205 0 0); --primary-foreground: oklch(97% 0.014 254.604);
--secondary: oklch(0.269 0 0); --secondary: oklch(0.274 0.006 286.033);
--secondary-foreground: oklch(0.985 0 0); --secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0); --muted: oklch(0.274 0.006 286.033);
--muted-foreground: oklch(0.708 0 0); --muted-foreground: oklch(0.705 0.015 286.067);
--accent: oklch(0.269 0 0); --accent: oklch(0.274 0.006 286.033);
--accent-foreground: oklch(0.985 0 0); --accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216); --destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%); --border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%); --input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0); --ring: oklch(0.488 0.243 264.376);
--radius: 0.65rem;
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.21 0.006 285.885);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(62.3% 0.214 259.815);
--sidebar-primary-foreground: oklch(97% 0.014 254.604);
--sidebar-accent: oklch(0.3 0.006 286.033);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.488 0.243 264.376);
--selection: oklch(0.92 0.004 286.32);
--selection-foreground: oklch(0.21 0.006 285.885);
} }
@layer base { @layer base {
* { * {

View File

@@ -16,7 +16,9 @@ func Load() (Plan, error) {
return Plan{}, err return Plan{}, err
} }
var menus [3][7]string var menus [3][7]string
records, err := csv.NewReader(strings.NewReader(string(f))).ReadAll() reader := csv.NewReader(strings.NewReader(string(f)))
reader.Comma = ';'
records, err := reader.ReadAll()
for y := 0; y <= 2; y++ { for y := 0; y <= 2; y++ {
for x := 0; x <= 6; x++ { for x := 0; x <= 6; x++ {
menus[y][x] = records[y+1][x+1] menus[y][x] = records[y+1][x+1]

View File

@@ -1,4 +1,4 @@
,Montag,Dienstag,Mittwoch,Donnerstag,Freitag,Samstag,Sonntag ;Montag;Dienstag;Mittwoch;Donnerstag;Freitag;Samstag;Sonntag
Frühstück,Test1,Test2,Test3,Test4,Test5,Test6,Test7 Frühstück;Test1;Test2;Test3;Test4;Test5;Test6;Test7
Mittagessen,Test8,Test9,Test10,Test11,Test12,Test13,Test14 Mittagessen;Test8;Test9;Test10;Test11;Test12;Test13;Test14
Abendessen,Test15,Test16,Test17,Test18,Test19,Test20,Test21 Abendessen;Test15;Test16;Test17;Test18;Test19;Test20;Test21
1 Montag Dienstag Mittwoch Donnerstag Freitag Samstag Sonntag
2 Frühstück Test1 Test2 Test3 Test4 Test5 Test6 Test7
3 Mittagessen Test8 Test9 Test10 Test11 Test12 Test13 Test14
4 Abendessen Test15 Test16 Test17 Test18 Test19 Test20 Test21

View File

@@ -130,7 +130,7 @@ templ Row(props ...RowProps) {
} }
class={ class={
utils.TwMerge( utils.TwMerge(
"border-b transition-colors hover:bg-muted/50", "border-b transition-colors",
utils.If(p.Selected, "data-[tui-table-state-selected]:bg-muted"), utils.If(p.Selected, "data-[tui-table-state-selected]:bg-muted"),
p.Class, p.Class,
), ),

View File

@@ -453,7 +453,7 @@ func Row(props ...RowProps) templ.Component {
p = props[0] p = props[0]
} }
var templ_7745c5c3_Var18 = []any{utils.TwMerge( var templ_7745c5c3_Var18 = []any{utils.TwMerge(
"border-b transition-colors hover:bg-muted/50", "border-b transition-colors",
utils.If(p.Selected, "data-[tui-table-state-selected]:bg-muted"), utils.If(p.Selected, "data-[tui-table-state-selected]:bg-muted"),
p.Class, p.Class,
), ),

View File

@@ -34,7 +34,7 @@ func Home(plan csv.Plan) templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent templ_7745c5c3_Var1 = templ.NopComponent
} }
ctx = templ.ClearChildren(ctx) ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html lang=\"en\" class=\"dark\"><head><meta charset=\"UTF-8\"><title>Menüplan</title><link href=\"https://coder.base2.sh/@b2dennis/rose-coyote-52.main/apps/code-server/proxy/8080/assets/css/output.css\" type=\"text/css\" rel=\"stylesheet\"></head><body class=\"w-full flex dark\">") templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html lang=\"en\"><head><meta charset=\"UTF-8\"><title>Menüplan</title><link href=\"https://coder.base2.sh/@b2dennis/rose-coyote-52.main/apps/code-server/proxy/8080/assets/css/output.css\" type=\"text/css\" rel=\"stylesheet\"></head><body class=\"w-full\">")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }