# AdPlatform Registration Portal Client-facing registration wizard for new AdPlatform prospects. Collects contact and business information through a multi-step wizard, then submits to the Registration Azure Function for review. ## Architecture ``` RegistrationPortal/ React frontend (webpack) ├── src/ │ ├── auth/ Entra External ID (CIAM) auth provider │ ├── context/ RegistrationContext — wizard state management │ ├── services/ API service layer (calls Registration Function) │ ├── components/ │ │ ├── Shell.jsx Layout wrapper (matches Admin shell) │ │ ├── ProgressStepper Visual step indicator │ │ └── steps/ Individual wizard step components │ └── styles/ CSS (custom properties, matches Admin theme) │ Registration/ Azure Function backend (already deployed) ├── Functions/ HTTP endpoints (register, pending, complete, reject) ├── Data/ Interface + SqlDataService (SP caller) └── Mock/ In-memory mock for development ``` ## Wizard Flow | Step | Component | API Call | |------|-----------|----------| | 0 - Sign In | `SignInStep` | Entra External ID (MSAL popup) | | 1 - Contact | `ContactStep` | (client-side only) | | 2 - Business | `BusinessStep` | (client-side only) | | 3 - Review | `ReviewStep` | `POST /api/registration/register` | | 4 - Confirm | `ConfirmationStep` | — | Data is collected across steps 1–2 and submitted as a single `RegisterRequest` in step 3, matching the Registration Function's contract. ## Data Contract The wizard submits a `RegisterRequest` matching `RegistrationFunctions.cs`: ```json { "businessName": "Acme Corp", "websiteUrl": "https://acme.com", "businessCategory": "retail", "businessDescription": "...", "contactName": "Jane Smith", "contactEmail": "jane@acme.com", "contactPhone": "(555) 123-4567", "entraSubjectId": "entra-abc123" } ``` ## Development ```bash npm install npm start # http://localhost:3001 ``` Runs in **mock mode** when `API_BASE_URL` is empty in `authConfig.js`. To connect to the real Registration Function, update the constants in `src/auth/authConfig.js`: ```js export const API_BASE_URL = 'https://adpregapi.usimdev.com'; export const API_FUNCTION_KEY = 'your-function-key'; ``` ## Auth Setup (TODO) The `AuthProvider` is currently **stubbed** for development. To wire Entra External ID: 1. Create an External ID tenant in Azure 2. Register an app with redirect URI = portal URL 3. Enable social providers (Google, Apple) in the External ID user flows 4. Update `authConfig.js` with tenant details 5. Replace stub logic in `AuthProvider.jsx` with MSAL `loginPopup` / `logoutPopup` ## Approval Flow After submission, the Registration Function holds the application as `Pending`. The Admin console's **Clients → Pending** tab shows these for review. When an admin clicks **Approve**, the system: 1. Calls `POST /api/registration/action/{id}/complete` with a `platformClientId` 2. Creates advertising sub-accounts with naming convention: `ADP-{BusinessName}-{ClientId}` - Google Ads (under MCC) - Meta Business Manager - TikTok Business Center 3. Creates the client record in the main platform database ## Conventions - **React**: Context pattern (createContext / useHook / Provider), no prop drilling - **CSS**: Custom properties, DM Sans, kebab-case class names - **Build**: Webpack + Babel (matches Admin project) - **API**: Azure Functions with `x-functions-key` auth - **Backend**: `@action`/`@rqst`/`@resp` stored procedure pattern