// @requirements REQ-PRODUCT-REACT REQ-PRODUCT-FORM-PERMISSIONS REQ-PRODUCT-MOBILE import {createElement as h,useState,useEffect} from 'react'; import {FormPermissionProvider,FormPermissionField,useFormPermissionSnapshot} from 'notabenda/react'; function Workspace({offer,dark=false}){ const state=useFormPermissionSnapshot(),[ready,setReady]=useState(false),[result,setResult]=useState('A local draft. Email permission is recorded separately.');useEffect(()=>{setReady(true);},[]); const current=state.status==='retired'?'Context closed':state.recovery?.withdrawalPending?'Withdrawal awaiting confirmation':['loading','submitting'].includes(state.status)?'Awaiting confirmation':state.status==='error'?'Not confirmed':state.allowed?'Permission recorded':state.current?.reason==='withdrawn'?'Withdrawn':state.current?'Off':'Not checked'; const fact=(label,value)=>h('div',{key:label},h('dt',null,label),h('dd',null,h('output',null,value))); return h('main',{id:'main',className:'nb-document'},h('p',{className:'nb-eyebrow'},'Notabenda · React form permissions'),h('h1',null,'Email permissions',h('br'),'with React'),h('p',null,'Prepare a workspace draft and save an email permission separately. Submitting the draft does not change the permission.'), h('form',{className:'permission-workspace',onSubmit:event=>{event.preventDefault();setResult('Draft prepared: '+event.currentTarget.elements.namedItem('title').value+'. Email permission is unchanged.');}}, h('div',{className:'permission-draft-heading'},h('span',{className:'nb-eyebrow'},'01 / YOUR READING SPACE'),h('h2',null,'Workspace draft'),h('label',{htmlFor:'react-workspace-title'},'Workspace title'),h('input',{id:'react-workspace-title',name:'title',defaultValue:'Weekend reading',maxLength:80,required:true}),h('p',{className:'permission-destination'},'Email destination ',h('strong',null,'reader@example.test'))), h('div',{id:'permission-field'},h(FormPermissionField,{fallback:h('p',null,'Permission controls require JavaScript. You can read the privacy policy below.')})), h('div',{className:'permission-draft-action'},h('button',{className:'nb-choice-button',type:'submit',disabled:!ready},'Prepare workspace draft ',h('span',{'aria-hidden':'true'},'→')),h('p',{role:'status','data-workspace-result':true},result))), h('section',{className:'permission-context'},h('p',{className:'nb-eyebrow'},'02 / THE RECORDED STATE'),h('h2',null,'Permission and recording status'),h('dl',{className:'permission-state'},fact('Email updates',current),fact('Choice revision',state.current?.revision??'—'),fact('Permission version',offer.revision),fact('Last acknowledged action',state.receipt?state.receipt.action==='grant'?'Grant recorded':'Withdrawal recorded':'None this visit')), h('p',null,'Checking the box is a draft. Saving permission waits for acknowledgment. Preparing the workspace draft changes no saved permission.'), state.receipt?h('a',{href:'/demo/admin/permissions/record?id='+state.receipt.id},'Inspect this record ↗'):null,h('a',{href:'/demo/admin/permissions'},'Open permission history ↗'),h('a',{href:dark?'/form-permissions/react/':'/dark/form-permissions/react/'},dark?'Light theme ↗':'Midnight theme ↗'),h('a',{href:'/form-permissions/'},'Plain JavaScript example ↗'),h('details',null,h('summary',null,'Follow the React integration'),h('p',null,'The host creates the controller once. The provider and field subscribe to it; they never read, retry or submit on mount. The host explicitly loads saved state. This example sends no email.'),h('a',{href:'/guide/react#ordinary-form-permissions'},'Integration guide ↗')))); } export function ReactPermissionApp({controller,offer,dark}){return h(FormPermissionProvider,{controller},h(Workspace,{offer,dark}));}