spine-framework-portal 0.2.13 → 0.2.14
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.
- package/components/PortalHeader.tsx +21 -1
- package/index.tsx +2 -0
- package/package.json +1 -1
- package/pages/team/TeamPage.tsx +12 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useState } from 'react'
|
|
2
2
|
import { NavLink, useNavigate } from 'react-router-dom'
|
|
3
|
-
import { Ticket, Users, BookOpen, GraduationCap, Store, LayoutGrid, User, LogOut, Save } from 'lucide-react'
|
|
3
|
+
import { Ticket, Users, BookOpen, GraduationCap, Store, LayoutGrid, User, LogOut, Save, UserPlus } from 'lucide-react'
|
|
4
4
|
import { useAuth } from '@core/contexts/AuthContext'
|
|
5
5
|
import { useAppPath } from '@core/hooks/useAppPath'
|
|
6
6
|
import { Button } from '@core/components/ui/button'
|
|
@@ -22,6 +22,10 @@ export function PortalHeader() {
|
|
|
22
22
|
const { user, logout } = useAuth()
|
|
23
23
|
const appPath = useAppPath()
|
|
24
24
|
const navigate = useNavigate()
|
|
25
|
+
|
|
26
|
+
const isTeamAdmin =
|
|
27
|
+
user?.is_system_admin ||
|
|
28
|
+
user?.roles?.some((r: string) => r === 'member_admin')
|
|
25
29
|
const [accountOpen, setAccountOpen] = useState(false)
|
|
26
30
|
const [displayName, setDisplayName] = useState(user?.full_name || user?.email?.split('@')[0] || '')
|
|
27
31
|
|
|
@@ -68,6 +72,22 @@ export function PortalHeader() {
|
|
|
68
72
|
{label}
|
|
69
73
|
</NavLink>
|
|
70
74
|
))}
|
|
75
|
+
{isTeamAdmin && (
|
|
76
|
+
<NavLink
|
|
77
|
+
to={appPath('/team')}
|
|
78
|
+
className={({ isActive }) =>
|
|
79
|
+
[
|
|
80
|
+
'flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors',
|
|
81
|
+
isActive
|
|
82
|
+
? 'bg-accent text-accent-foreground'
|
|
83
|
+
: 'text-muted-foreground hover:text-foreground hover:bg-accent/50',
|
|
84
|
+
].join(' ')
|
|
85
|
+
}
|
|
86
|
+
>
|
|
87
|
+
<UserPlus size={14} />
|
|
88
|
+
Team
|
|
89
|
+
</NavLink>
|
|
90
|
+
)}
|
|
71
91
|
</nav>
|
|
72
92
|
|
|
73
93
|
<Button
|
package/index.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import { PortalFooter } from './components/PortalFooter'
|
|
|
7
7
|
import { useCurrentApp } from '@core/contexts/AppContext'
|
|
8
8
|
|
|
9
9
|
const HomePage = lazy(() => import('./pages/HomePage').then(m => ({ default: m.HomePage })))
|
|
10
|
+
const TeamPage = lazy(() => import('./pages/team/TeamPage').then(m => ({ default: m.TeamPage })))
|
|
10
11
|
const TicketsPage = lazy(() => import('./pages/TicketsPage').then(m => ({ default: m.TicketsPage })))
|
|
11
12
|
const CommunityPage = lazy(() => import('./pages/CommunityPage').then(m => ({ default: m.CommunityPage })))
|
|
12
13
|
const CoursesPage = lazy(() => import('./pages/CoursesPage').then(m => ({ default: m.CoursesPage })))
|
|
@@ -33,6 +34,7 @@ function PortalLayout() {
|
|
|
33
34
|
<Route path="community" element={<CommunityPage />} />
|
|
34
35
|
<Route path="marketplace" element={<MarketplacePage />} />
|
|
35
36
|
<Route path="developer" element={<DeveloperSettingsPage />} />
|
|
37
|
+
<Route path="team" element={<TeamPage />} />
|
|
36
38
|
<Route path="*" element={<Navigate to="." replace />} />
|
|
37
39
|
</Routes>
|
|
38
40
|
</div>
|
package/package.json
CHANGED
package/pages/team/TeamPage.tsx
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* @stability stable
|
|
6
6
|
*
|
|
7
7
|
* Portal team management page. Visible to member_admin only.
|
|
8
|
-
* Invites are scoped to the current user's account with
|
|
9
|
-
*
|
|
8
|
+
* Invites are scoped to the current user's account with selectable portal roles.
|
|
9
|
+
* List is filtered to portal roles only (member, member_admin).
|
|
10
10
|
*
|
|
11
11
|
* Route: /portal/team
|
|
12
12
|
*
|
|
@@ -17,6 +17,13 @@ import React from 'react'
|
|
|
17
17
|
import { InviteManager } from '../../../../.framework/src/components/shared/InviteManager'
|
|
18
18
|
import { useAuth } from '../../../../.framework/src/contexts/AuthContext'
|
|
19
19
|
|
|
20
|
+
const PORTAL_ROLES = [
|
|
21
|
+
{ slug: 'member', name: 'Member' },
|
|
22
|
+
{ slug: 'member_admin', name: 'Member Admin' },
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
const PORTAL_ROLE_SLUGS = PORTAL_ROLES.map(r => r.slug).join(',')
|
|
26
|
+
|
|
20
27
|
export function TeamPage() {
|
|
21
28
|
const { user } = useAuth()
|
|
22
29
|
|
|
@@ -37,14 +44,15 @@ export function TeamPage() {
|
|
|
37
44
|
<div>
|
|
38
45
|
<h1 className="text-2xl font-semibold text-slate-900">Team</h1>
|
|
39
46
|
<p className="mt-1 text-sm text-slate-500">
|
|
40
|
-
Invite members and manage access
|
|
47
|
+
Invite members and manage access to your account.
|
|
41
48
|
</p>
|
|
42
49
|
</div>
|
|
43
50
|
|
|
44
51
|
<InviteManager
|
|
45
52
|
scope="account"
|
|
46
53
|
accountId={user?.account_id}
|
|
47
|
-
|
|
54
|
+
allowedRoles={PORTAL_ROLES}
|
|
55
|
+
roleSlugsFilter={PORTAL_ROLE_SLUGS}
|
|
48
56
|
/>
|
|
49
57
|
</div>
|
|
50
58
|
)
|