phone.tsx (2473B)
1 import { PersonalPhoneNumber } from "#core/domain/personal_phone_number.ts"; 2 import PhoneNumberInput from "#http/islands/phone_number_input.tsx"; 3 import { AppState } from "#http/routes/_middleware.ts"; 4 import { Handlers, PageProps } from "$fresh/src/server/types.ts"; 5 import * as V from "$valita"; 6 7 type Props = { 8 invalid: boolean; 9 conflict: boolean; 10 }; 11 12 export const handler: Handlers<Props, AppState<"/register/phone">> = { 13 async GET(_req, ctx) { 14 const { app, forms, formContext } = ctx.state; 15 const { customerInfo } = app; 16 if (formContext === null) { 17 return forms.redirect({ form: "/connect", context: { back: "/" } }); 18 } 19 const { back, conflict } = formContext; 20 if (forms.session === null) { 21 return forms.redirect({ 22 form: "/connect", 23 context: { back: { form: "/register/phone", context: { back } } }, 24 }); 25 } 26 if (conflict) { 27 return ctx.render({ invalid: true, conflict: true }); 28 } 29 const result = await customerInfo.execute({ uuid: forms.session.uuid }); 30 if (!result.exists) { 31 return ctx.renderNotFound(); 32 } 33 if (result.phoneNumberVerified) { 34 return forms.redirect(back); 35 } 36 return ctx.render({ invalid: false, conflict: false }); 37 }, 38 39 async POST(req, ctx) { 40 const { forms, formContext } = ctx.state; 41 if (formContext === null) { 42 return forms.redirect({ form: "/connect", context: { back: "/" } }); 43 } 44 const { back } = formContext; 45 if (forms.session === null) { 46 return forms.redirect({ 47 form: "/connect", 48 context: { back: { form: "/register/phone", context: { back } } }, 49 }); 50 } 51 const { phoneNumber } = await forms.inputs( 52 req, 53 V.object({ phoneNumber: V.string() }), 54 ); 55 try { 56 return forms.redirect({ 57 form: "/verify/sms", 58 context: { 59 phoneNumber: new PersonalPhoneNumber(phoneNumber).toString(), 60 back, 61 }, 62 }); 63 } catch { 64 return ctx.render({ invalid: true, conflict: false }); 65 } 66 }, 67 }; 68 69 export default function RegisterPages({ data }: PageProps<Props>) { 70 return ( 71 <article> 72 <header style="text-align: center;"> 73 <b>Phone number registration</b> 74 </header> 75 <form method="POST"> 76 <PhoneNumberInput error={data.invalid} conflict={data.conflict} /> 77 <div role="group"> 78 <button type="submit">Register</button> 79 </div> 80 </form> 81 </article> 82 ); 83 }