diff --git a/src/components/PlansSection.tsx b/src/components/PlansSection.tsx index daacaaa..e520482 100644 --- a/src/components/PlansSection.tsx +++ b/src/components/PlansSection.tsx @@ -1,68 +1,45 @@ -import { useState } from "react"; -import { Check, Loader2 } from "lucide-react"; +import { useState, useMemo } from "react"; +import { Loader2 } from "lucide-react"; import { useShopifyProducts } from "@/hooks/useShopifyProducts"; import { useCartStore } from "@/stores/cartStore"; import { toast } from "sonner"; -const planDetails = [ - { - name: "Liten", - kgPerWeek: "3 kg", - priceWeekExclVat: "975", - employeeRecommendation: "1–10 anställda", - features: [ - "3 kg kakor per vecka", - "Veckoleverans", - "Betala direkt eller med Klarna", - ], - shopifyHandle: "liten-kakabonnemang-3-kg-vecka", - isPremium: false, - }, - { - name: "Mellan", - kgPerWeek: "5 kg", - priceWeekExclVat: "1 625", - employeeRecommendation: "10–25 anställda", - features: [ - "5 kg kakor per vecka", - "Veckoleverans", - "Betala direkt eller med Klarna", - ], - shopifyHandle: "mellan-kakabonnemang-5-kg-vecka", - isPremium: false, - }, - { - name: "Stor", - kgPerWeek: "10 kg", - priceWeekExclVat: "4 000", - employeeRecommendation: "25+ anställda", - features: [ - "10 kg kakor per vecka", - "Veckoleverans", - "Betala direkt eller med Klarna", - "Prioriterad leverans", - ], - shopifyHandle: "stor-kakabonnemang-10-kg-vecka", - isPremium: true, - }, +const PRICE_PER_KG = 325; +const KG_PER_EMPLOYEE = 0.3; + +// Map recommended kg to the closest available Shopify subscription plan +const availablePlans = [ + { kg: 3, handle: "liten-kakabonnemang-3-kg-vecka", name: "Liten" }, + { kg: 5, handle: "mellan-kakabonnemang-5-kg-vecka", name: "Mellan" }, + { kg: 10, handle: "stor-kakabonnemang-10-kg-vecka", name: "Stor" }, ]; +const pickPlan = (kg: number) => { + const match = availablePlans.find((p) => p.kg >= kg); + return match || availablePlans[availablePlans.length - 1]; +}; + const PlansSection = () => { - const [selectedPlan, setSelectedPlan] = useState(""); + const [employees, setEmployees] = useState(10); const [checkoutLoading, setCheckoutLoading] = useState(false); - + const { products, isLoading: productsLoading } = useShopifyProducts("product_type:Abonnemang"); const { addItem, clearCart, isLoading: cartLoading } = useCartStore(); - const handleSelectPlan = async (plan: typeof planDetails[0]) => { - // Find the matching Shopify product - const shopifyProduct = products.find(p => p.node.handle === plan.shopifyHandle); - + const recommendedKg = useMemo( + () => Math.max(1, Math.round(employees * KG_PER_EMPLOYEE)), + [employees] + ); + const weeklyPrice = recommendedKg * PRICE_PER_KG; + + const handleStart = async () => { + const plan = pickPlan(recommendedKg); + const shopifyProduct = products.find((p) => p.node.handle === plan.handle); + if (!shopifyProduct) { toast.error("Kunde inte hitta produkten"); return; } - const variant = shopifyProduct.node.variants.edges[0]?.node; if (!variant) { toast.error("Ingen variant tillgänglig"); @@ -70,12 +47,8 @@ const PlansSection = () => { } setCheckoutLoading(true); - setSelectedPlan(plan.name); - try { - // Clear any existing cart items first for a clean order clearCart(); - await addItem({ product: shopifyProduct, variantId: variant.id, @@ -84,12 +57,11 @@ const PlansSection = () => { quantity: 1, selectedOptions: variant.selectedOptions || [], }); - - toast.success(`${plan.name} tillagt i varukorgen`, { + toast.success(`Abonnemang tillagt (${plan.name} – ${plan.kg} kg/vecka)`, { description: "Klicka på varukorgen för att gå till betalning", }); - } catch (error) { - console.error('Add to cart error:', error); + } catch (e) { + console.error(e); toast.error("Något gick fel"); } finally { setCheckoutLoading(false); @@ -99,84 +71,90 @@ const PlansSection = () => { const isLoading = productsLoading || cartLoading || checkoutLoading; return ( -
-
- {/* Section header */} -
-
-

- Våra Abonnemang +
+
+ {/* Header */} +
+
+

+ Hur många anställda har ni?

-

- Välj det abonnemang som passar ert företag bäst +

+ Vi rekommenderar automatiskt rätt mängd kakor utifrån antalet medarbetare.

- {/* Plans grid */} -
- {planDetails.map((plan, index) => ( + {/* Calculator card */} +
+ {/* Employee count display */} +
- - {/* Plan header */} -
-

- {plan.name} -

-

- {plan.employeeRecommendation} -

-
- - {/* Price info */} -
-
- {plan.kgPerWeek}/vecka -
-
- - {plan.priceWeekExclVat} - - kr/v -
-
- - {/* Features - hidden on mobile */} -
    - {plan.features.map((feature, i) => ( -
  • - - {feature} -
  • - ))} -
- - {/* CTA Button - always at bottom */} - + {employees}
- ))} +
+ {employees === 1 ? "anställd" : "anställda"} +
+
+ + {/* Slider */} +
+ setEmployees(parseInt(e.target.value, 10))} + className="calculator-slider w-full" + aria-label="Antal anställda" + /> +
+ 1 + 100 +
+
+ + {/* Result */} +
+
+
+ Rekommenderad mängd +
+
+ {recommendedKg} kg +
+
per vecka
+
+ +
+
+ Pris per vecka +
+
+ {weeklyPrice.toLocaleString("sv-SE")} kr +
+
exklusive moms
+
+ + +
- -
); diff --git a/src/index.css b/src/index.css index a5378bd..166ca4e 100644 --- a/src/index.css +++ b/src/index.css @@ -175,4 +175,47 @@ .text-balance { text-wrap: balance; } + + /* Calculator slider — minimal, exclusive */ + .calculator-slider { + -webkit-appearance: none; + appearance: none; + height: 4px; + background: hsl(var(--border)); + border-radius: 999px; + outline: none; + cursor: pointer; + transition: background 0.2s ease; + } + .calculator-slider:hover { + background: hsl(var(--muted)); + } + .calculator-slider::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 26px; + height: 26px; + border-radius: 50%; + background: hsl(var(--primary)); + border: 3px solid hsl(var(--card)); + box-shadow: 0 2px 10px hsl(var(--primary) / 0.35); + cursor: grab; + transition: transform 0.15s ease, box-shadow 0.15s ease; + } + .calculator-slider::-webkit-slider-thumb:hover { + transform: scale(1.1); + box-shadow: 0 4px 16px hsl(var(--primary) / 0.5); + } + .calculator-slider::-webkit-slider-thumb:active { + cursor: grabbing; + } + .calculator-slider::-moz-range-thumb { + width: 26px; + height: 26px; + border-radius: 50%; + background: hsl(var(--primary)); + border: 3px solid hsl(var(--card)); + box-shadow: 0 2px 10px hsl(var(--primary) / 0.35); + cursor: grab; + } }