sms.tsx (3188B)
1 import CodeInput from "#http/islands/code_input.tsx"; 2 import DelayedButton from "#http/islands/delayed_button.tsx"; 3 import { AppState } from "#http/routes/_middleware.ts"; 4 import { Handlers, PageProps } from "$fresh/server.ts"; 5 import * as V from "$valita"; 6 7 type Props = { 8 invalid: boolean; 9 delay: number; 10 blocked: boolean; 11 }; 12 13 export const handler: Handlers<Props, AppState<"/verify/sms">> = { 14 async GET(req, ctx) { 15 const { app, forms, formContext } = ctx.state; 16 const { phoneRegister } = app; 17 18 if (formContext === null) { 19 return forms.redirect({ 20 form: "/connect", 21 context: { 22 back: forms.link({ 23 form: "/register/phone", 24 context: { back: "/" }, 25 }).href, 26 }, 27 }); 28 } 29 30 const { phoneNumber, back } = formContext; 31 if (forms.session === null) { 32 return forms.redirect({ 33 form: "/connect", 34 context: { 35 back: forms.link({ form: "/register/phone", context: { back } }).href, 36 }, 37 }); 38 } 39 40 const result = await phoneRegister.execute({ 41 uuid: forms.session.uuid, 42 phoneNumber, 43 }); 44 45 if (result.status === "verified") { 46 return forms.redirect(back); 47 } 48 49 if (result.status === "invalid") { 50 return forms.redirect({ 51 form: "/register/phone", 52 context: { back }, 53 }); 54 } 55 56 if (result.status === "conflict") { 57 return forms.redirect({ 58 form: "/register/phone", 59 context: { back, conflict: true }, 60 }); 61 } 62 63 return ctx.render({ 64 invalid: false, 65 delay: result.delay, 66 blocked: false, 67 }); 68 }, 69 70 async POST(req, ctx) { 71 const { app, forms, formContext } = ctx.state; 72 const { phoneVerifySms } = app; 73 74 if (formContext === null) { 75 return forms.redirect({ 76 form: "/connect", 77 context: { 78 back: { form: "/register/phone", context: { back: "/" } }, 79 }, 80 }); 81 } 82 83 const { back } = formContext; 84 if (forms.session === null) { 85 return forms.redirect({ 86 form: "/connect", 87 context: { 88 back: { form: "/register/phone", context: { back } }, 89 }, 90 }); 91 } 92 93 const { code } = await forms.inputs(req, V.object({ code: V.string() })); 94 95 const result = await phoneVerifySms.execute({ 96 uuid: forms.session.uuid, 97 code, 98 }); 99 100 if (result.status === "verified") { 101 return forms.redirect(back); 102 } 103 104 return ctx.render({ 105 invalid: false, 106 delay: result.delay, 107 blocked: result.status === "blocked", 108 }); 109 }, 110 }; 111 112 export default function VerifySmsPages({ url, data }: PageProps<Props>) { 113 return ( 114 <article> 115 <header style="text-align: center;"> 116 <b>Phone number verification</b> 117 </header> 118 <form method="POST"> 119 <CodeInput error={data.invalid} /> 120 <div role="group"> 121 <DelayedButton delay={data.delay} href={url.href}> 122 Resend 123 </DelayedButton> 124 {!data.blocked && 125 ( 126 <button type="submit"> 127 Verify 128 </button> 129 )} 130 </div> 131 </form> 132 </article> 133 ); 134 }