From b89c272ceeb07ea1d576abb54499a1d0320a89c9 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:02:37 +0000 Subject: [PATCH 1/8] Changes Co-authored-by: wolfoftyreso-debug <250630591+wolfoftyreso-debug@users.noreply.github.com> --- supabase/functions/create-account/index.ts | 91 ++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 supabase/functions/create-account/index.ts diff --git a/supabase/functions/create-account/index.ts b/supabase/functions/create-account/index.ts new file mode 100644 index 0000000..6df5ab3 --- /dev/null +++ b/supabase/functions/create-account/index.ts @@ -0,0 +1,91 @@ +import { createClient } from "https://esm.sh/@supabase/supabase-js@2.45.0"; +import { z } from "npm:zod@3.23.8"; + +const corsHeaders = { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": + "authorization, x-client-info, x-supabase-client-platform, x-supabase-api-version, apikey, content-type", + "Access-Control-Allow-Methods": "POST, OPTIONS", +}; + +const BodySchema = z.object({ + email: z.string().trim().email().max(255), + password: z.string().min(8).max(100), + company: z.string().trim().max(200).optional().default(""), + phone: z.string().trim().max(30).optional().default(""), +}); + +const admin = createClient( + Deno.env.get("SUPABASE_URL")!, + Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!, +); + +Deno.serve(async (req) => { + if (req.method === "OPTIONS") return new Response("ok", { headers: corsHeaders }); + if (req.method !== "POST") { + return new Response(JSON.stringify({ error: "Method not allowed" }), { + status: 405, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }); + } + + try { + const parsed = BodySchema.safeParse(await req.json()); + if (!parsed.success) { + return new Response( + JSON.stringify({ error: "Ogiltiga fält", details: parsed.error.flatten().fieldErrors }), + { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }, + ); + } + const { email, password, company, phone } = parsed.data; + + // Try to create user with email_confirm=true so they can sign in immediately + const { data: created, error: createErr } = await admin.auth.admin.createUser({ + email, + password, + email_confirm: true, + user_metadata: { company, phone }, + }); + + if (createErr) { + const msg = createErr.message || ""; + const alreadyExists = + msg.toLowerCase().includes("already") || + msg.toLowerCase().includes("registered") || + msg.toLowerCase().includes("exists"); + if (alreadyExists) { + return new Response(JSON.stringify({ ok: true, existed: true }), { + status: 200, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }); + } + console.error("createUser error:", createErr); + return new Response(JSON.stringify({ error: msg }), { + status: 400, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }); + } + + // Best-effort update profile + if (created?.user?.id) { + await admin + .from("profiles") + .update({ + company_name: company || null, + phone: phone || null, + }) + .eq("user_id", created.user.id); + } + + return new Response(JSON.stringify({ ok: true, existed: false }), { + status: 200, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }); + } catch (err: any) { + console.error("create-account error:", err); + return new Response(JSON.stringify({ error: err?.message ?? "Något gick fel" }), { + status: 500, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }); + } +}); From 7062fb583c1bf95e7081792830adef3b276a7d33 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:02:41 +0000 Subject: [PATCH 2/8] Changes Co-authored-by: wolfoftyreso-debug <250630591+wolfoftyreso-debug@users.noreply.github.com> --- supabase/config.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/supabase/config.toml b/supabase/config.toml index 7724f20..c6cfd2c 100644 --- a/supabase/config.toml +++ b/supabase/config.toml @@ -12,6 +12,9 @@ verify_jwt = false [functions.submit-order] verify_jwt = false +[functions.create-account] +verify_jwt = false + [functions.create-checkout] verify_jwt = false From d7c9e0b2c0e7fe5a1a9b67b08017919a55df0af1 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:02:46 +0000 Subject: [PATCH 3/8] Changes Co-authored-by: wolfoftyreso-debug <250630591+wolfoftyreso-debug@users.noreply.github.com> --- src/components/PlansSection.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/PlansSection.tsx b/src/components/PlansSection.tsx index 398ba33..746a195 100644 --- a/src/components/PlansSection.tsx +++ b/src/components/PlansSection.tsx @@ -1,5 +1,5 @@ import { useState, useMemo, useEffect } from "react"; -import { Loader2, CheckCircle2, CreditCard, FileText, ChevronsUpDown, Check } from "lucide-react"; +import { Loader2, CheckCircle2, CreditCard, FileText, ChevronsUpDown, Check, Lock, Eye, EyeOff, Sparkles } from "lucide-react"; import { supabase } from "@/integrations/supabase/client"; import { useAuth } from "@/hooks/useAuth"; import { toast } from "sonner"; From b917df93ffef141a661c00562849841404a89b86 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:02:50 +0000 Subject: [PATCH 4/8] Changes Co-authored-by: wolfoftyreso-debug <250630591+wolfoftyreso-debug@users.noreply.github.com> --- src/components/PlansSection.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/PlansSection.tsx b/src/components/PlansSection.tsx index 746a195..3cbcda7 100644 --- a/src/components/PlansSection.tsx +++ b/src/components/PlansSection.tsx @@ -86,6 +86,7 @@ const formSchema = z.object({ .refine(isStockholmPostalCode, "Vi levererar endast inom Storstockholm (100 00 – 199 99)"), stad: z.string().trim().min(1, "Fyll i stad").max(100), kommentarer: z.string().trim().max(1000).optional(), + password: z.string().max(100).optional(), }); type Method = "card" | "invoice"; From 0d67ea812437b72681f1e4e7c7c381aab0f8835a Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:02:56 +0000 Subject: [PATCH 5/8] Changes Co-authored-by: wolfoftyreso-debug <250630591+wolfoftyreso-debug@users.noreply.github.com> --- src/components/PlansSection.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/PlansSection.tsx b/src/components/PlansSection.tsx index 3cbcda7..119433f 100644 --- a/src/components/PlansSection.tsx +++ b/src/components/PlansSection.tsx @@ -101,6 +101,7 @@ const PlansSection = () => { const [errors, setErrors] = useState>({}); const [clientSecret, setClientSecret] = useState(null); const [cityOpen, setCityOpen] = useState(false); + const [showPassword, setShowPassword] = useState(false); const [form, setForm] = useState({ företag: "", epost: "", @@ -109,6 +110,7 @@ const PlansSection = () => { postnummer: "", stad: "", kommentarer: "", + password: "", }); const filteredCities = useMemo(() => { From 5df1ce68fa464e00590511dad919ffd66c58845c Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:03:04 +0000 Subject: [PATCH 6/8] Changes Co-authored-by: wolfoftyreso-debug <250630591+wolfoftyreso-debug@users.noreply.github.com> --- src/components/PlansSection.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/components/PlansSection.tsx b/src/components/PlansSection.tsx index 119433f..fe64b66 100644 --- a/src/components/PlansSection.tsx +++ b/src/components/PlansSection.tsx @@ -190,6 +190,15 @@ const PlansSection = () => { return; } + // Password required for guests (auto-create account) + if (!user) { + const pw = form.password || ""; + if (pw.length < 8) { + setErrors((prev) => ({ ...prev, password: "Lösenordet måste vara minst 8 tecken" })); + return; + } + } + if (!hasPaymentsConfigured()) { toast.error("Betalningar är inte konfigurerade ännu."); return; From 77aa579ee4612162c0c7a72e0be8ac595d51a5bc Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:03:15 +0000 Subject: [PATCH 7/8] Changes Co-authored-by: wolfoftyreso-debug <250630591+wolfoftyreso-debug@users.noreply.github.com> --- src/components/PlansSection.tsx | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/components/PlansSection.tsx b/src/components/PlansSection.tsx index fe64b66..6081a2b 100644 --- a/src/components/PlansSection.tsx +++ b/src/components/PlansSection.tsx @@ -206,6 +206,33 @@ const PlansSection = () => { setSubmitting(true); try { + // Auto-create account for guests, then sign in + if (!user && form.password) { + const { data: accData, error: accErr } = await supabase.functions.invoke("create-account", { + body: { + email: result.data.epost, + password: form.password, + company: result.data.företag, + phone: result.data.telefon ?? "", + }, + }); + if (accErr) throw accErr; + if ((accData as any)?.error) throw new Error((accData as any).error); + + const { error: signInErr } = await supabase.auth.signInWithPassword({ + email: result.data.epost, + password: form.password, + }); + if (signInErr) { + if ((accData as any)?.existed) { + throw new Error( + "Ett konto finns redan för denna e-post. Fel lösenord — logga in eller använd 'Glömt lösenord'.", + ); + } + throw signInErr; + } + } + const body = { method, employees, From 807c208226a4ad087236f4858ab459737ee733af Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:03:32 +0000 Subject: [PATCH 8/8] Changes Co-authored-by: wolfoftyreso-debug <250630591+wolfoftyreso-debug@users.noreply.github.com> --- src/components/PlansSection.tsx | 52 +++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/components/PlansSection.tsx b/src/components/PlansSection.tsx index 6081a2b..72c66f1 100644 --- a/src/components/PlansSection.tsx +++ b/src/components/PlansSection.tsx @@ -492,6 +492,58 @@ const PlansSection = () => { + {!user && ( +
+
+
+
+ +
+
+
+ Ditt konto skapas automatiskt +
+

+ Välj ett lösenord så loggar vi in dig direkt. Hantera ditt abonnemang, ändra leveranser och se fakturor i "Mitt konto" när som helst. +

+
+
+ + +
+ + + +
+ {errors.password ? ( +

{errors.password}

+ ) : ( +

+ Använd minst 8 tecken. Vi rekommenderar en blandning av bokstäver och siffror. +

+ )} +
+ )} + +