# Min Side Expert Context > Use this skill when working on `/min-side/` routes, user authentication, access control, or member portal features in BIM Verdi. --- ## 1. Architecture Overview ### Router System Min Side uses a single router template that maps URL paths to part files: ``` template-minside-router.php ↓ inc/minside-helpers.php (route definitions) ↓ parts/minside/{part-file}.php ``` **Key files:** - `template-minside-router.php` - Main router template - `inc/minside-helpers.php` - Route definitions + helper functions - `header-minside.php` - Authenticated header - `parts/minside/*.php` - Individual view templates ### Adding a New Route 1. Add route to `bimverdi_get_minside_routes()` in `inc/minside-helpers.php`: ```php 'my-route' => 'my-route', // Simple route 'parent/child' => 'parent-child', // Nested route ``` 2. Create template file: `parts/minside/{part-file}.php` 3. Optionally add to navigation in `bimverdi_get_minside_nav()` --- ## 2. Complete Route Map ### Active Routes (17+) | URL Path | Part File | Description | |----------|-----------|-------------| | `/min-side/` | dashboard.php | Main dashboard | | `/min-side/profil/` | profil.php | View profile | | `/min-side/profil/rediger/` | profil-rediger.php | Edit profile | | `/min-side/profil/passord/` | profil-passord.php | Change password | | `/min-side/foretak/` | foretak-detail.php | View company | | `/min-side/foretak/rediger/` | foretak-rediger.php | Edit company (hovedkontakt only) | | `/min-side/verktoy/` | verktoy-list.php | List tools | | `/min-side/verktoy/registrer/` | verktoy-registrer.php | Register new tool | | `/min-side/verktoy/rediger/` | verktoy-rediger.php | Edit tool (?id=X) | | `/min-side/kunnskapskilder/` | kunnskapskilder-list.php | List knowledge sources | | `/min-side/kunnskapskilder/registrer/` | kunnskapskilder-registrer.php | Register knowledge source | | `/min-side/kunnskapskilder/rediger/` | kunnskapskilder-rediger.php | Edit knowledge source | | `/min-side/artikler/` | artikler-list.php | List articles | | `/min-side/artikler/skriv/` | artikler-skriv.php | Write new article | | `/min-side/arrangementer/` | arrangementer-list.php | Events list | | `/min-side/prosjektideer/` | prosjektideer-list.php | Project ideas list | | `/min-side/invitasjoner/` | invitasjoner-list.php | Invite colleagues (hovedkontakt only) | ### Legacy Route Aliases These redirect to new routes for backward compatibility: - `/min-side/mine-verktoy/` → verktoy-list - `/min-side/registrer-verktoy/` → verktoy-registrer - `/min-side/rediger-verktoy/` → verktoy-rediger - `/min-side/rediger-foretak/` → foretak-rediger - `/min-side/rediger-profil/` → profil-rediger - `/min-side/endre-passord/` → profil-passord - `/min-side/skriv-artikkel/` → artikler-skriv --- ## 3. User Roles & Access Control ### Account Types | Type | Definition | Access Level | |------|------------|--------------| | `profil` | User without company | Limited - can browse, attend events | | `foretak` | User linked to company | Full - can create content | | `guest` | Not logged in | No Min Side access | ### WordPress Roles | Role | Description | Has Company | |------|-------------|-------------| | `medlem` | Free member | Optional | | `tilleggskontakt` | Invited by hovedkontakt | Yes (required) | | `deltaker` | Paying member (standard) | Yes (required) | | `prosjektdeltaker` | Paying member (mid-tier) | Yes (required) | | `partner` | Paying member (top tier) | Yes (required) | **Important:** `deltaker`, `prosjektdeltaker`, and `partner` have IDENTICAL capabilities. The difference is business/pricing only. ### Hovedkontakt vs Tilleggskontakt | Capability | Tilleggskontakt | Hovedkontakt | |------------|-----------------|--------------| | Create tools | Yes | Yes | | Write articles | Yes | Yes | | Register knowledge sources | Yes | Yes | | Submit project ideas | Yes | Yes | | Edit own content | Yes | Yes | | Delete content | No (admin) | No (admin) | | Edit company profile | **No** | **Yes** | | View team members | Yes | Yes | | Remove team members | No | **Yes** | | Transfer hovedkontakt | No | **Yes** | | Invite colleagues | No | **Yes** | ### Feature Access Control **Requires Company (`foretak` account type):** ```php const COMPANY_REQUIRED_FEATURES = [ 'register_tool', // Registrere verktøy 'edit_tool', // Redigere verktøy 'write_article', // Skrive artikler 'submit_case', // Sende inn prosjektidéer 'join_temagruppe', // Velge temagrupper 'company_profile', // Redigere foretaksprofil 'view_members_full', // Se fullt medlemsinnhold ]; ``` **Open to All Logged-In Users:** ```php const OPEN_FEATURES = [ 'view_dashboard', // Se Min Side dashboard 'edit_profile', // Redigere egen profil 'view_catalog', // Se medlemskatalog 'view_tools', // Se verktøykatalog 'register_event', // Melde seg på arrangementer 'view_events', // Se arrangementer 'connect_company', // Koble til foretak ]; ``` --- ## 4. Helper Functions ### URL Helpers ```php // Get Min Side base URL bimverdi_minside_base_url(); // Returns: https://site.com/min-side // Generate Min Side URL bimverdi_minside_url('verktoy'); // /min-side/verktoy/ bimverdi_minside_url('verktoy/rediger', ['id' => 123]); // /min-side/verktoy/rediger/?id=123 // Get current route bimverdi_get_current_route(); // Returns: 'verktoy/rediger' // Check if on specific route bimverdi_is_minside_route('verktoy'); // true for /verktoy/ and /verktoy/rediger/ bimverdi_is_minside_route(['profil', 'foretak']); // Multiple routes // Get primary route segment bimverdi_get_primary_route(); // 'verktoy' from 'verktoy/rediger' ``` ### Company & User Helpers ```php // Check if user has company bimverdi_user_has_company($user_id); // Returns: bool // Get user's company ID bimverdi_get_user_company($user_id); // Returns: int|false // Check if user is hovedkontakt bimverdi_is_hovedkontakt($user_id, $company_id); // Returns: bool // Check if company is active/approved bimverdi_is_company_active($company_id); // Returns: bool // Get account type bimverdi_get_account_type($user_id); // Returns: 'profil', 'foretak', or 'guest' ``` ### Access Control Helpers ```php // Check feature access bimverdi_can_access('register_tool'); // Returns: bool // Render locked feature UI BIMVerdi_Access_Control::render_locked_ui('register_tool', 'Custom message'); // Render locked card component bimverdi_locked_card('Title', 'Description', 'icon-name', 'feature'); // Render "connect to company" CTA bimverdi_connect_company_cta(); ``` ### Navigation Helper ```php // Get navigation structure $nav = bimverdi_get_minside_nav(); // Returns array with: label, url, icon, badge, routes ``` --- ## 5. Company ID Storage (Legacy Migration) User's company is stored in user_meta. Check these keys **in order**: 1. `bimverdi_company_id` (new standard) 2. `bim_verdi_company_id` (legacy) 3. ACF field `tilknyttet_foretak` (fallback) **Always use the helper function** `bimverdi_get_user_company()` which handles all three. --- ## 6. ACF Field Reference ### Foretak (Company) - CPT: `foretak` ```php get_field('hovedkontaktperson', $company_id); // User ID of primary contact get_field('er_aktiv_deltaker', $company_id); // bool - is active member get_field('organisasjonsnummer', $company_id); // Norwegian org number get_field('bedriftsnavn', $company_id); // Company name (or post_title) get_field('beskrivelse', $company_id); // Company description get_field('logo', $company_id); // Attachment ID get_field('adresse', $company_id); // Street address get_field('postnummer', $company_id); // Postal code get_field('poststed', $company_id); // City get_field('land', $company_id); // Country get_field('telefon', $company_id); // Phone get_field('epost', $company_id); // Email get_field('nettside', $company_id); // Website URL ``` ### Verktøy (Tool) - CPT: `verktoy` ```php get_field('tilknyttet_foretak', $tool_id); // Company ID that owns the tool get_field('eier_leverandor', $tool_id); // Owner/vendor company get_field('logo', $tool_id); // Tool logo get_field('vendor', $tool_id); // Vendor name get_field('type_verktoey', $tool_id); // Tool type get_field('plattform', $tool_id); // Platform(s) ``` ### Kunnskapskilde (Knowledge Source) - CPT: `kunnskapskilde` ```php get_field('registrert_av', $kilde_id); // User ID who registered get_field('tilknyttet_bedrift', $kilde_id); // Company ID get_field('kunnskapskilde_navn', $kilde_id); // Name get_field('kildetype', $kilde_id); // Type (standard, veileder, etc.) get_field('utgiver', $kilde_id); // Publisher get_field('ekstern_lenke', $kilde_id); // External URL get_field('kort_beskrivelse', $kilde_id); // Short description ``` ### Arrangement (Event) - CPT: `arrangement` ```php get_field('arrangement_dato', $event_id); // Date get_field('tidspunkt_start', $event_id); // Start time get_field('tidspunkt_slutt', $event_id); // End time get_field('arrangement_type', $event_id); // Type (digitalt, fysisk, hybrid) get_field('sted_by', $event_id); // City get_field('sted_adresse', $event_id); // Address get_field('pamelding_url', $event_id); // Registration URL get_field('maks_deltakere', $event_id); // Max participants ``` ### Prosjektidé (Project Idea) - CPT: `case` ```php get_field('temagruppe', $idea_id); // Related theme group ``` ### User Fields ```php get_field('tilknyttet_foretak', 'user_' . $user_id); // Company ID ``` --- ## 7. CPT Constants Defined in `bim-verdi-core/includes/class-content-types.php`: ```php BV_CPT_COMPANY = 'foretak' // Member companies BV_CPT_TOOL = 'verktoy' // Software tools BV_CPT_EVENT = 'arrangement' // Events/meetings BV_CPT_REGISTRATION = 'pamelding' // Event registrations BV_CPT_IDEA = 'case' // Project ideas (private) BV_CPT_PROJECT = 'prosjekt' // Pilot projects BV_CPT_THEME_GROUP = 'theme_group' // Temagrupper BV_CPT_ARTICLE = 'artikkel' // Member articles ``` --- ## 8. Gravity Forms ### Form IDs - **Form 10:** Email signup (Step 1) - Email verification flow - **Form 11:** Account activation (Step 2) - Name + password ### Form Handlers Located in `mu-plugins/bimverdi-email-verification.php` and `bimverdi-gforms-setup.php`. ### Usage in Templates Forms are embedded via PHP or shortcode in registration flows, not typically in Min Side views. --- ## 9. Design System Rules **Always follow** `claude/UI-CONTRACT.md` when building Min Side templates. ### Key Principles 1. **P1:** Whitespace + dividers as primary structure (no "boxes everywhere") 2. **P2:** Clickability must be explicit (only buttons/links are interactive) 3. **P3:** Information ≠ handling (info in borderless sections, actions in buttons) 4. **P4:** Show only what exists (hide empty fields) 5. **P5:** Rolig, consistent enterprise style (minimal visual noise) ### Layout Widths - Standard content: `max-width: 1200-1280px` - Form pages: `max-width: 960px` - Spacing scale: 8px increments ### Color Palette ``` Text Primary: #1A1A1A text-[#1A1A1A] Text Secondary: #5A5A5A text-[#5A5A5A] Dividers: #D6D1C6 border-[#D6D1C6] Background: #F7F5EF bg-[#F7F5EF] CTA/Orange: #FF8B5E bg-[#FF8B5E] ``` ### Button Component Use `bimverdi_button()` from `parts/components/button.php`: ```php bimverdi_button([ 'text' => 'Lagre', 'variant' => 'primary', // primary, secondary, tertiary, danger 'size' => 'medium', // small, medium, large 'icon' => 'save', // Lucide icon name 'href' => '/url', // Makes it a link ]); ``` ### Icons Use **Lucide icons** (https://lucide.dev): - `layout-dashboard` - Dashboard - `wrench` - Tools - `file-text` - Articles - `lightbulb` - Ideas - `calendar` - Events - `building-2` - Company - `user-plus` - Invitations - `chevron-right` - Navigate --- ## 10. Temagrupper (Theme Groups) **Important:** Temagrupper are linked to **foretak (companies)**, NOT individual users. - All users linked to a foretak can view the company's temagrupper - Only hovedkontakt can change temagruppe memberships - Temagruppe selection is a company-level setting --- ## 11. Common Patterns ### Access Check in Template ```php ``` ### Page Header Component ```php get_template_part('parts/components/page-header', null, [ 'title' => 'Page Title', 'description' => 'Optional subtitle text', 'icon' => 'wrench', // Lucide icon 'actions' => [ [ 'text' => 'Primary Action', 'href' => '/url', 'variant' => 'primary', 'icon' => 'plus', ], ], ]); ``` ### Breadcrumb Navigation ```php ``` ### Data Table Pattern ```php
Column
Content
``` --- ## 12. Debug Mode Add `?debug_router=1` to any Min Side URL (admin only) to see: - Request URI - Current Route - Part File - Query Var --- ## 13. Files Quick Reference | Purpose | File Path | |---------|-----------| | Router template | `template-minside-router.php` | | Route definitions | `inc/minside-helpers.php` | | Access control | `mu-plugins/bimverdi-access-control.php` | | Role definitions | `mu-plugins/bimverdi-custom-roles.php` | | Authenticated header | `header-minside.php` | | View templates | `parts/minside/*.php` | | Button component | `parts/components/button.php` | | Page header | `parts/components/page-header.php` | | Design rules | `claude/UI-CONTRACT.md` |