diff --git a/src/components/AbonnemangForm.tsx b/src/components/AbonnemangForm.tsx
index 64be198..bb60f99 100644
--- a/src/components/AbonnemangForm.tsx
+++ b/src/components/AbonnemangForm.tsx
@@ -11,6 +11,19 @@ const isStockholmPostalCode = (postalCode: string) => {
return num >= 10000 && num <= 19999;
};
+// Get error message for postal code (for real-time validation display)
+const getPostalCodeError = (postalCode: string) => {
+ if (!postalCode || postalCode.trim() === "") return null;
+ const cleaned = postalCode.replace(/\s/g, "");
+ if (cleaned.length < 5) return null; // Don't show error while typing
+ if (!/^\d{5}$/.test(cleaned)) return "Ange ett giltigt postnummer (5 siffror)";
+ const num = parseInt(cleaned, 10);
+ if (num < 10000 || num > 19999) {
+ return "Vi levererar endast inom Storstockholm (100 00 – 199 99)";
+ }
+ return null;
+};
+
const formSchema = z.object({
företag: z.string().trim().min(1, "Fyll i företagsnamn").max(100),
epost: z.string().trim().email("Ange en giltig e-postadress").max(255),
@@ -243,10 +256,16 @@ const AbonnemangForm = ({ selectedPlan, onClose }: AbonnemangFormProps) => {
placeholder="t.ex. 114 32"
value={formData.postnummer}
onChange={handleChange}
- className="w-full px-4 py-3 rounded-sm bg-background border border-border text-foreground focus:outline-none focus:ring-2 focus:ring-primary/30"
+ className={`w-full px-4 py-3 rounded-sm bg-background border text-foreground focus:outline-none focus:ring-2 ${
+ getPostalCodeError(formData.postnummer)
+ ? "border-destructive focus:ring-destructive/30"
+ : "border-border focus:ring-primary/30"
+ }`}
/>
- {errors.postnummer && (
-
{errors.postnummer}
+ {(errors.postnummer || getPostalCodeError(formData.postnummer)) && (
+
+ {errors.postnummer || getPostalCodeError(formData.postnummer)}
+
)}
diff --git a/src/pages/Account.tsx b/src/pages/Account.tsx
index b318be9..04c0d5d 100644
--- a/src/pages/Account.tsx
+++ b/src/pages/Account.tsx
@@ -11,10 +11,26 @@ import Header from "@/components/Header";
import { Save, Package } from "lucide-react";
import { useShopifyProducts } from "@/hooks/useShopifyProducts";
+// Validate Stockholm postal codes (100 00 - 199 99)
+const isStockholmPostalCode = (postalCode: string) => {
+ if (!postalCode || postalCode.trim() === "") return true; // Allow empty
+ const cleaned = postalCode.replace(/\s/g, "");
+ if (!/^\d{5}$/.test(cleaned)) return false;
+ const num = parseInt(cleaned, 10);
+ return num >= 10000 && num <= 19999;
+};
+
const profileSchema = z.object({
company_name: z.string().trim().max(100, { message: "Företagsnamn får max vara 100 tecken" }).optional(),
street_address: z.string().trim().max(200, { message: "Gatuadress får max vara 200 tecken" }).optional(),
- postal_code: z.string().trim().max(10, { message: "Postnummer får max vara 10 tecken" }).optional(),
+ postal_code: z
+ .string()
+ .trim()
+ .max(10, { message: "Postnummer får max vara 10 tecken" })
+ .refine((val) => isStockholmPostalCode(val), {
+ message: "Vi levererar endast inom Storstockholm (100 00 – 199 99)",
+ })
+ .optional(),
city: z.string().trim().max(100, { message: "Ort får max vara 100 tecken" }).optional(),
});
@@ -25,6 +41,18 @@ interface ProfileData {
city: string;
}
+const getPostalCodeError = (postalCode: string) => {
+ if (!postalCode || postalCode.trim() === "") return null;
+ const cleaned = postalCode.replace(/\s/g, "");
+ if (cleaned.length < 5) return null; // Don't show error while typing
+ if (!/^\d{5}$/.test(cleaned)) return "Ange ett giltigt postnummer (5 siffror)";
+ const num = parseInt(cleaned, 10);
+ if (num < 10000 || num > 19999) {
+ return "Vi levererar endast inom Storstockholm (100 00 – 199 99)";
+ }
+ return null;
+};
+
const Account = () => {
const [profile, setProfile] = useState
({
company_name: "",
@@ -219,7 +247,7 @@ const Account = () => {