スキル一覧に戻る
aharstad91

minside

by aharstad91

0🍴 0📅 2026年1月24日
GitHubで見るManusで実行

SKILL.md

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:
'my-route'       => 'my-route',        // Simple route
'parent/child'   => 'parent-child',    // Nested route
  1. Create template file: parts/minside/{part-file}.php

  2. Optionally add to navigation in bimverdi_get_minside_nav()


2. Complete Route Map

Active Routes (17+)

URL PathPart FileDescription
/min-side/dashboard.phpMain dashboard
/min-side/profil/profil.phpView profile
/min-side/profil/rediger/profil-rediger.phpEdit profile
/min-side/profil/passord/profil-passord.phpChange password
/min-side/foretak/foretak-detail.phpView company
/min-side/foretak/rediger/foretak-rediger.phpEdit company (hovedkontakt only)
/min-side/verktoy/verktoy-list.phpList tools
/min-side/verktoy/registrer/verktoy-registrer.phpRegister new tool
/min-side/verktoy/rediger/verktoy-rediger.phpEdit tool (?id=X)
/min-side/kunnskapskilder/kunnskapskilder-list.phpList knowledge sources
/min-side/kunnskapskilder/registrer/kunnskapskilder-registrer.phpRegister knowledge source
/min-side/kunnskapskilder/rediger/kunnskapskilder-rediger.phpEdit knowledge source
/min-side/artikler/artikler-list.phpList articles
/min-side/artikler/skriv/artikler-skriv.phpWrite new article
/min-side/arrangementer/arrangementer-list.phpEvents list
/min-side/prosjektideer/prosjektideer-list.phpProject ideas list
/min-side/invitasjoner/invitasjoner-list.phpInvite 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

TypeDefinitionAccess Level
profilUser without companyLimited - can browse, attend events
foretakUser linked to companyFull - can create content
guestNot logged inNo Min Side access

WordPress Roles

RoleDescriptionHas Company
medlemFree memberOptional
tilleggskontaktInvited by hovedkontaktYes (required)
deltakerPaying member (standard)Yes (required)
prosjektdeltakerPaying member (mid-tier)Yes (required)
partnerPaying member (top tier)Yes (required)

Important: deltaker, prosjektdeltaker, and partner have IDENTICAL capabilities. The difference is business/pricing only.

Hovedkontakt vs Tilleggskontakt

CapabilityTilleggskontaktHovedkontakt
Create toolsYesYes
Write articlesYesYes
Register knowledge sourcesYesYes
Submit project ideasYesYes
Edit own contentYesYes
Delete contentNo (admin)No (admin)
Edit company profileNoYes
View team membersYesYes
Remove team membersNoYes
Transfer hovedkontaktNoYes
Invite colleaguesNoYes

Feature Access Control

Requires Company (foretak account type):

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:

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

// 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

// 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

// 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();
// 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

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

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

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

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

get_field('temagruppe', $idea_id);             // Related theme group

User Fields

get_field('tilknyttet_foretak', 'user_' . $user_id);  // Company ID

7. CPT Constants

Defined in bim-verdi-core/includes/class-content-types.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:

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
// At top of template part
$user_id = get_current_user_id();
$company_id = bimverdi_get_user_company($user_id);

// Require company
if (!$company_id) {
    bimverdi_connect_company_cta();
    return;
}

// Require hovedkontakt
if (!bimverdi_is_hovedkontakt($user_id, $company_id)) {
    wp_redirect(bimverdi_minside_url('foretak'));
    exit;
}
?>

Page Header Component

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',
        ],
    ],
]);
<nav class="text-sm mb-6" aria-label="Brødsmulesti">
    <ol class="flex items-center gap-2 text-[#5A5A5A]">
        <li><a href="<?php echo bimverdi_minside_url(); ?>" class="hover:text-[#1A1A1A]">Min side</a></li>
        <li><span class="text-[#D6D1C6]">/</span></li>
        <li><a href="<?php echo bimverdi_minside_url('parent'); ?>" class="hover:text-[#1A1A1A]">Parent</a></li>
        <li><span class="text-[#D6D1C6]">/</span></li>
        <li class="text-[#1A1A1A] font-medium">Current Page</li>
    </ol>
</nav>

Data Table Pattern

<div class="overflow-x-auto">
    <table class="w-full">
        <thead>
            <tr class="border-b border-[#D6D1C6]">
                <th class="text-left py-3 px-4 text-xs font-medium text-[#5A5A5A] uppercase tracking-wide">Column</th>
            </tr>
        </thead>
        <tbody class="divide-y divide-[#E5E2DB]">
            <tr class="hover:bg-[#F7F5EF]/50">
                <td class="py-4 px-4">Content</td>
            </tr>
        </tbody>
    </table>
</div>

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

PurposeFile Path
Router templatetemplate-minside-router.php
Route definitionsinc/minside-helpers.php
Access controlmu-plugins/bimverdi-access-control.php
Role definitionsmu-plugins/bimverdi-custom-roles.php
Authenticated headerheader-minside.php
View templatesparts/minside/*.php
Button componentparts/components/button.php
Page headerparts/components/page-header.php
Design rulesclaude/UI-CONTRACT.md

スコア

総合スコア

40/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です