// VPS-flyt: plan → OS/lokasjon/vertsnavn → handlevogn. Ingen domenesteg. import React, { useState } from 'react'; const NS = window.STWORDER; const HOSTNAME_RE = /^([a-z0-9-]+\.)*[a-z0-9-]+(\.[a-zæøå]{2,})?$/i; function Field({ label, hint, children }) { return ( ); } function VpsConfigurator({ plan }) { const { useI18n, nok, Btn, StepHeading, localName } = NS.ui; const { t, lang } = useI18n(); const [os, setOs] = useState(NS.data.vpsOs[0]); const [loc, setLoc] = useState(NS.data.vpsLocations[0].id); const [hostname, setHostname] = useState(''); const [cycle, setCycle] = useState('monthly'); const hostnameOk = hostname.trim() === '' || HOSTNAME_RE.test(hostname.trim()); const due = NS.store.cyclePrice(plan.monthly, cycle); const location = NS.data.vpsLocations.find((l) => l.id === loc); function add() { NS.store.add({ type: 'vps', planId: plan.id, name: plan.name, cycle, monthly: plan.monthly, os, location: loc, hostname: hostname.trim() || null, }); NS.bus.emit('cart:open'); } const selectCls = 'w-full rounded-lg border border-gray-300 bg-white px-3 py-2.5 text-sm text-navy outline-none focus:border-brand'; return (
{t('vps.step2')} – {plan.name}
setHostname(e.target.value)} placeholder="server1.mittdomene.no" autoCapitalize="none" spellCheck="false" className={selectCls + (hostnameOk ? '' : ' border-red-400')} />
{t('cart.dueToday')}
{nok(due)}
{t('common.addToCart')}
); } function VpsFlow() { const { useI18n, nok, ProductCard, StepHeading, PageHero, localName } = NS.ui; const { t, lang } = useI18n(); const [selId, setSelId] = useState(null); const selected = NS.data.vpsPlans.find((p) => p.id === selId) || null; return (
{t('vps.step1')}
{NS.data.vpsPlans.map((p) => ( setSelId(p.id)} selected={selId === p.id} /> ))}
{selected ? : null}
); } NS.flows = NS.flows || {}; NS.flows.Vps = VpsFlow;