All checks were successful
Deploy Development / deploy (push) Successful in 41s
Test Suite / pytest-backend (push) Successful in 30s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 7s
Test Suite / playwright-tests (push) Successful in 24s
- Added new API endpoint to retrieve join requests accessible by platform admins and club admins. - Implemented frontend components to display join requests in the inbox, including navigation updates and badge notifications. - Enhanced sidebar and navigation to conditionally show inbox based on user permissions. - Updated styles for inbox components and added responsive design for dashboard integration. - Introduced context management for inbox state and notifications on join request actions.
88 lines
2.1 KiB
JavaScript
88 lines
2.1 KiB
JavaScript
import {
|
|
createContext,
|
|
useCallback,
|
|
useContext,
|
|
useEffect,
|
|
useMemo,
|
|
useState,
|
|
} from 'react'
|
|
import api from '../utils/api'
|
|
|
|
const OrgInboxContext = createContext(null)
|
|
|
|
export function canAccessOrgInbox(user) {
|
|
if (!user?.id) return false
|
|
if (user.role === 'admin' || user.role === 'superadmin') return true
|
|
return (user.clubs || []).some((c) => (c.roles || []).includes('club_admin'))
|
|
}
|
|
|
|
/** Nach Annahme/Ablehnung: Posteingang-Badges & Widget aktualisieren */
|
|
export function notifyOrgInboxChanged() {
|
|
window.dispatchEvent(new Event('shinkan:inbox-changed'))
|
|
}
|
|
|
|
export function OrgInboxProvider({ user, children }) {
|
|
const [items, setItems] = useState([])
|
|
const canAccess = useMemo(() => canAccessOrgInbox(user), [user])
|
|
|
|
const refresh = useCallback(async () => {
|
|
if (!canAccess) {
|
|
setItems([])
|
|
return
|
|
}
|
|
try {
|
|
const data = await api.getInboxJoinRequests()
|
|
setItems(Array.isArray(data) ? data : [])
|
|
} catch {
|
|
setItems([])
|
|
}
|
|
}, [canAccess])
|
|
|
|
useEffect(() => {
|
|
if (!canAccess) {
|
|
setItems([])
|
|
return undefined
|
|
}
|
|
let cancelled = false
|
|
;(async () => {
|
|
try {
|
|
const data = await api.getInboxJoinRequests()
|
|
if (!cancelled) setItems(Array.isArray(data) ? data : [])
|
|
} catch {
|
|
if (!cancelled) setItems([])
|
|
}
|
|
})()
|
|
return () => {
|
|
cancelled = true
|
|
}
|
|
}, [canAccess, user?.id])
|
|
|
|
useEffect(() => {
|
|
const onChange = () => {
|
|
refresh()
|
|
}
|
|
window.addEventListener('shinkan:inbox-changed', onChange)
|
|
return () => window.removeEventListener('shinkan:inbox-changed', onChange)
|
|
}, [refresh])
|
|
|
|
const value = useMemo(
|
|
() => ({
|
|
inboxJoinRequests: items,
|
|
inboxCount: items.length,
|
|
refreshOrgInbox: refresh,
|
|
canAccessOrgInbox: canAccess,
|
|
}),
|
|
[items, refresh, canAccess]
|
|
)
|
|
|
|
return <OrgInboxContext.Provider value={value}>{children}</OrgInboxContext.Provider>
|
|
}
|
|
|
|
export function useOrgInbox() {
|
|
const ctx = useContext(OrgInboxContext)
|
|
if (!ctx) {
|
|
throw new Error('useOrgInbox must be used within OrgInboxProvider')
|
|
}
|
|
return ctx
|
|
}
|