@igamingcareer/igaming-components 1.0.85 → 1.0.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/Readme.md +147 -1
  2. package/dist/index.js +1597 -1597
  3. package/dist/index.mjs +20891 -18568
  4. package/package.json +1 -1
package/Readme.md CHANGED
@@ -123,7 +123,130 @@ export function FollowCompaniesExample({ company }: { company: Company }) {
123
123
  }
124
124
  ```
125
125
 
126
- Use `followDisabled` to block interactions for unauthenticated users, and `isFollowing` to keep the UI in sync with your data source.
126
+ ## Company admin shell layout
127
+
128
+ The CompanyAdminShell component now renders the admin tabs internally. It handles tab routing, renders the built-in admin views, and surfaces update events so the parent can persist changes.
129
+
130
+ ### Permission system
131
+
132
+ Permissions decide whether a tab is visible and whether fields render as editable inputs or read-only text. Use a boolean per section:
133
+
134
+ ```ts
135
+ export type CompanyAdminPermissions = {
136
+ canViewOverview?: boolean;
137
+ canManageProducts?: boolean;
138
+ canManagePeople?: boolean;
139
+ canManageJobs?: boolean;
140
+ canManageEvents?: boolean;
141
+ canManageNews?: boolean;
142
+ canManageSettings?: boolean;
143
+ };
144
+ ```
145
+
146
+ ### Update events
147
+
148
+ Each admin section emits update events so the parent can save to the backend and update local state.
149
+
150
+ ```ts
151
+ import type { CompanyAdminUpdateEvent } from "@igamingcareer/igaming-components";
152
+
153
+ const handleUpdate = async (event: CompanyAdminUpdateEvent) => {
154
+ console.log("update event", event);
155
+ // call backend API
156
+ // update local state based on event.type
157
+ };
158
+ ```
159
+
160
+ ### Example usage
161
+
162
+ ```tsx
163
+ import { useState } from "react";
164
+ import {
165
+ CompanyAdminShell,
166
+ type AdminTab,
167
+ type CompanyAdminPermissions,
168
+ type CompanyAdminUpdateEvent,
169
+ } from "@igamingcareer/igaming-components";
170
+
171
+ export function CompanyAdminExample({ company }: { company: Company }) {
172
+ const [activeTab, setActiveTab] = useState<AdminTab>("overview");
173
+ const [isSaving, setIsSaving] = useState(false);
174
+
175
+ const permissions: CompanyAdminPermissions = {
176
+ canViewOverview: true,
177
+ canManageProducts: true,
178
+ canManagePeople: false,
179
+ canManageJobs: true,
180
+ canManageEvents: true,
181
+ canManageNews: false,
182
+ canManageSettings: true,
183
+ };
184
+
185
+ const handleUpdate = async (event: CompanyAdminUpdateEvent) => {
186
+ setIsSaving(true);
187
+ try {
188
+ // call backend API
189
+ console.log("update", event);
190
+ } finally {
191
+ setIsSaving(false);
192
+ }
193
+ };
194
+
195
+ return (
196
+ <CompanyAdminShell
197
+ company={company}
198
+ role="admin"
199
+ permissions={permissions}
200
+ activeTab={activeTab}
201
+ onTabChange={setActiveTab}
202
+ onUpdate={handleUpdate}
203
+ isSaving={isSaving}
204
+ />
205
+ );
206
+ }
207
+ ```
208
+
209
+ ### CompanyAdminShell props
210
+
211
+ | Prop | Type | Description |
212
+ | --- | --- | --- |
213
+ | `company` | `Company` | Full company object used for header and admin sections. |
214
+ | `companyName` | `string` | Optional override for the display name shown in the header. |
215
+ | `companySlug` | `string` | Optional override for the slug used in the header. |
216
+ | `activeTab` | `AdminTab` | Current active tab key (controlled). |
217
+ | `visibleTabs` | `AdminTab[]` | Tabs that should appear in the admin UI (optional override). |
218
+ | `onTabChange` | `(tab: AdminTab) => void` | Called when a user switches tabs. |
219
+ | `role` | `CompanyAdminRole` | Role label shown in the header (defaults to `admin`). |
220
+ | `permissions` | `CompanyAdminPermissions` | Permission map for tabs and editability. |
221
+ | `companyMeta` | `CompanyAdminCompanyMeta` | Optional metadata for the header summary. |
222
+ | `summaryStats` | `CompanyAdminSummaryStat[]` | Optional summary stats for the header (derived from `company` when omitted). |
223
+ | `onUpdate` | `(event: CompanyAdminUpdateEvent) => void \| Promise<void>` | Optional update callback for child sections. |
224
+ | `isSaving` | `boolean` | Optional saving state for buttons. |
225
+
226
+ ### Backend integration guide
227
+
228
+ 1. Listen for `CompanyAdminUpdateEvent` from the active admin tab.
229
+ 2. Call your backend endpoint for that section.
230
+ 3. Merge the returned data into your local `company` state.
231
+ 4. Provide the updated `company` back to the admin components.
232
+
233
+ ### Component patterns
234
+
235
+ - Each admin section owns local `formState` and emits a full payload via `onUpdate`.
236
+ - When `canEdit` is `false`, fields render as read-only text and edit controls are hidden.
237
+ - Use `isSaving` to lock save buttons and show spinners.
238
+
239
+ ### Best practices
240
+
241
+ - Use `onUpdate` to connect each tab to your backend and keep `company` state in sync.
242
+ - Use separate state slices for admin-only data (e.g., settings) if it is not part of the core company API.
243
+ - Guard any optional permissions with defaults so read-only views remain safe.
244
+
245
+ ### Troubleshooting
246
+
247
+ - **Nothing renders:** ensure the active tab is included in `visibleTabs` and has permission enabled.
248
+ - **Save button disabled:** verify `isSaving` is `false` and `canEdit` is `true`.
249
+ - **Updates not persisting:** confirm your parent handler merges the payload back into company state.
127
250
 
128
251
  ## Save company callbacks (CompanyCard + CompanyDetail)
129
252
 
@@ -222,6 +345,29 @@ export function CompanyDetailWithClaim({ company }: { company: Company }) {
222
345
  }
223
346
  ```
224
347
 
348
+ ## Claim company CTA (CompanyClaim)
349
+
350
+ Use the `CompanyClaim` component to render a minimal “Claim this company” CTA. It is fully controlled by props and emits a click event upward without any auth or API logic.
351
+
352
+ ```tsx
353
+ import { CompanyClaim } from "@igamingcareer/igaming-components";
354
+
355
+ export function CompanyClaimExample({ company, canClaim }: { company: Company; canClaim: boolean }) {
356
+ const handleClaimClick = () => {
357
+ // optional: analytics or open your claim flow
358
+ console.log("claim company", { companyId: company.id });
359
+ };
360
+
361
+ return (
362
+ <CompanyClaim
363
+ isClaimed={company.claimedStatus === "claimed"}
364
+ canClaim={canClaim}
365
+ onClaimClick={handleClaimClick}
366
+ />
367
+ );
368
+ }
369
+ ```
370
+
225
371
  ## CV upload from the dashboard
226
372
 
227
373
  The dashboard emits CV upload events so the host application can upload, store,