';
}
private static function field(string $name,string $label,string $type='text',string $value='',int $max=128): string {
$id=$name.'_'.bin2hex(random_bytes(3));
return '';
}
public function help(): void {
$this->displayContent('
Using your club workspace
Open Clubs and dues to view clubs assigned to your account. Club rosters and your season dues are available inside each club.
Site administrators create clubs, assign existing accounts, add seasons, and record dues and received payments. Contact your club administrator for membership or account assistance.
');
}
public function home(): void {
$service=new RosterService();$html='
';
if($p['reversal_serial'])$html.='Reversed: '.self::h($p['reversal_reason'].' by '.$p['reversal_actor'].' on '.$p['reversed_at']);
elseif($admin&&$active)$html.='Reverse incorrect payment
This preserves the original entry and restores the amount owed. It does not send a refund.
'.self::h($a['member_name']).': $'.number_format($a['amount_cents']/100,2).' adjustment; corrected total $'.number_format($a['corrected_amount_cents']/100,2).' — '.self::h($a['reason'].' ('.$a['actor'].', '.$a['created_at'].')').'
';
return $html.'
';
}
public function workspace(): void {
$service=new RosterService();if(!$service->ready()){$this->home();return;}
$clubRaw=$_POST['club_serial']??$_GET['club_serial']??'';$club=($clubRaw===''||$clubRaw==='0')?0:MaintenanceService::id($clubRaw);
if(($_SERVER['REQUEST_METHOD']??'GET')==='POST' && ($_POST['step']??'')!==''){
$service->requireAdministrator();$this->requireCsrf();
switch($_POST['step']){
case 'club':$club=$service->saveClub($club,$_POST['club_name']??'',$_POST['club_status']??'active');break;
case 'member':$service->saveMember($club,empty($_POST['membership_serial'])?0:MaintenanceService::id($_POST['membership_serial']),$_POST['identifier']??'',$_POST['membership_status']??'active',$_POST['joined_on']??'');break;
case 'season':$service->addSeason($club,$_POST['season_name']??'',$_POST['starts_on']??'',$_POST['ends_on']??'');break;
case 'charge':$service->charge($club,MaintenanceService::id($_POST['membership_serial']??null),MaintenanceService::id($_POST['season_serial']??null),$_POST['amount']??'');break;
case 'payment':$service->payment($club,MaintenanceService::id($_POST['due_serial']??null),$_POST['amount']??'',$_POST['paid_on']??'',$_POST['request_key']??'',$_POST['payment_method']??'unspecified',$_POST['payment_reference']??'');break;
case 'adjust':(new LedgerService())->adjust($club,MaintenanceService::id($_POST['due_serial']??null),$_POST['corrected_amount']??'',$_POST['reason']??'',$_POST['request_key']??'');break;
case 'reverse':(new LedgerService())->reverse($club,MaintenanceService::id($_POST['payment_serial']??null),$_POST['reason']??'',$_POST['request_key']??'');break;
default:throw new AppException('Unknown club action.');
}
$_SESSION['roster_notice']='Changes saved.';header('Location: main.php?Xaction=Roster.workspace&club_serial='.$club,true,303);exit;
}
$html='