✨(frontend) add admin side panel for room management
Introduce new dedicated side panel for room administration, providing centralized interface for admins to manage room settings and participants. Content will be added in the upcoming commits.
This commit is contained in:
committed by
aleb_the_flash
parent
7c46029f87
commit
5d89efec78
56
src/frontend/src/features/rooms/livekit/components/Admin.tsx
Normal file
56
src/frontend/src/features/rooms/livekit/components/Admin.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import { Div, H, Text } from '@/primitives'
|
||||
import { css } from '@/styled-system/css'
|
||||
import { Separator as RACSeparator } from 'react-aria-components'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export const Admin = () => {
|
||||
const { t } = useTranslation('rooms', { keyPrefix: 'admin' })
|
||||
|
||||
return (
|
||||
<Div
|
||||
display="flex"
|
||||
overflowY="scroll"
|
||||
padding="0 1.5rem"
|
||||
flexGrow={1}
|
||||
flexDirection="column"
|
||||
alignItems="start"
|
||||
>
|
||||
<Text variant="note" wrap="pretty" margin="md">
|
||||
{t('description')}
|
||||
</Text>
|
||||
<RACSeparator
|
||||
className={css({
|
||||
border: 'none',
|
||||
height: '1px',
|
||||
width: '100%',
|
||||
background: '#dadce0',
|
||||
})}
|
||||
/>
|
||||
<H
|
||||
lvl={2}
|
||||
className={css({
|
||||
fontWeight: 500,
|
||||
})}
|
||||
>
|
||||
{t('access.title')}
|
||||
</H>
|
||||
<Text
|
||||
variant="note"
|
||||
wrap="balance"
|
||||
className={css({
|
||||
textStyle: 'sm',
|
||||
})}
|
||||
margin={'md'}
|
||||
>
|
||||
{t('access.description')}
|
||||
</Text>
|
||||
<div
|
||||
className={css({
|
||||
marginTop: '1rem',
|
||||
})}
|
||||
>
|
||||
[WIP]
|
||||
</div>
|
||||
</Div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { ToggleButton } from '@/primitives'
|
||||
import { RiAdminLine } from '@remixicon/react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { css } from '@/styled-system/css'
|
||||
import { ToggleButtonProps } from '@/primitives/ToggleButton'
|
||||
import { useIsAdminOrOwner } from '../hooks/useIsAdminOrOwner'
|
||||
import { useSidePanel } from '../hooks/useSidePanel'
|
||||
|
||||
export const AdminToggle = ({
|
||||
variant = 'primaryTextDark',
|
||||
onPress,
|
||||
...props
|
||||
}: ToggleButtonProps) => {
|
||||
const { t } = useTranslation('rooms', { keyPrefix: 'controls.admin' })
|
||||
|
||||
const { isAdminOpen, toggleAdmin } = useSidePanel()
|
||||
const tooltipLabel = isAdminOpen ? 'open' : 'closed'
|
||||
|
||||
const hasAdminAccess = useIsAdminOrOwner()
|
||||
if (!hasAdminAccess) return
|
||||
|
||||
return (
|
||||
<div
|
||||
className={css({
|
||||
position: 'relative',
|
||||
display: 'inline-block',
|
||||
})}
|
||||
>
|
||||
<ToggleButton
|
||||
square
|
||||
variant={variant}
|
||||
aria-label={t(tooltipLabel)}
|
||||
tooltip={t(tooltipLabel)}
|
||||
isSelected={isAdminOpen}
|
||||
onPress={(e) => {
|
||||
toggleAdmin()
|
||||
onPress?.(e)
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
<RiAdminLine />
|
||||
</ToggleButton>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { ReactNode } from 'react'
|
||||
import { Chat } from '../prefabs/Chat'
|
||||
import { Transcript } from './Transcript'
|
||||
import { Effects } from './effects/Effects'
|
||||
import { Admin } from './Admin'
|
||||
|
||||
type StyledSidePanelProps = {
|
||||
title: string
|
||||
@@ -108,6 +109,7 @@ export const SidePanel = () => {
|
||||
isChatOpen,
|
||||
isSidePanelOpen,
|
||||
isTranscriptOpen,
|
||||
isAdminOpen,
|
||||
} = useSidePanel()
|
||||
const { t } = useTranslation('rooms', { keyPrefix: 'sidePanel' })
|
||||
|
||||
@@ -132,6 +134,9 @@ export const SidePanel = () => {
|
||||
<Panel isOpen={isTranscriptOpen}>
|
||||
<Transcript />
|
||||
</Panel>
|
||||
<Panel isOpen={isAdminOpen}>
|
||||
<Admin />
|
||||
</Panel>
|
||||
</StyledSidePanel>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ export enum PanelId {
|
||||
EFFECTS = 'effects',
|
||||
CHAT = 'chat',
|
||||
TRANSCRIPT = 'transcript',
|
||||
ADMIN = 'admin',
|
||||
}
|
||||
|
||||
export const useSidePanel = () => {
|
||||
@@ -16,8 +17,13 @@ export const useSidePanel = () => {
|
||||
const isEffectsOpen = activePanelId == PanelId.EFFECTS
|
||||
const isChatOpen = activePanelId == PanelId.CHAT
|
||||
const isTranscriptOpen = activePanelId == PanelId.TRANSCRIPT
|
||||
const isAdminOpen = activePanelId == PanelId.ADMIN
|
||||
const isSidePanelOpen = !!activePanelId
|
||||
|
||||
const toggleAdmin = () => {
|
||||
layoutStore.activePanelId = isAdminOpen ? null : PanelId.ADMIN
|
||||
}
|
||||
|
||||
const toggleParticipants = () => {
|
||||
layoutStore.activePanelId = isParticipantsOpen ? null : PanelId.PARTICIPANTS
|
||||
}
|
||||
@@ -40,10 +46,12 @@ export const useSidePanel = () => {
|
||||
toggleChat,
|
||||
toggleEffects,
|
||||
toggleTranscript,
|
||||
toggleAdmin,
|
||||
isChatOpen,
|
||||
isParticipantsOpen,
|
||||
isEffectsOpen,
|
||||
isSidePanelOpen,
|
||||
isTranscriptOpen,
|
||||
isAdminOpen,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { ChatToggle } from '../../components/controls/ChatToggle'
|
||||
import { ParticipantsToggle } from '../../components/controls/Participants/ParticipantsToggle'
|
||||
import { SupportToggle } from '../../components/controls/SupportToggle'
|
||||
import { TranscriptToggle } from '../../components/controls/TranscriptToggle'
|
||||
import { AdminToggle } from '../../components/AdminToggle'
|
||||
import { useSize } from '../../hooks/useResizeObserver'
|
||||
import { useState, RefObject } from 'react'
|
||||
import { Dialog, DialogTrigger, Popover } from 'react-aria-components'
|
||||
@@ -19,6 +20,7 @@ const NavigationControls = ({ onPress }: Partial<ToggleButtonProps>) => (
|
||||
<ParticipantsToggle onPress={onPress} />
|
||||
<TranscriptToggle onPress={onPress} />
|
||||
<SupportToggle onPress={onPress} />
|
||||
<AdminToggle onPress={onPress} />
|
||||
</>
|
||||
)
|
||||
|
||||
|
||||
@@ -97,6 +97,10 @@
|
||||
"open": "",
|
||||
"closed": ""
|
||||
},
|
||||
"admin": {
|
||||
"open": "",
|
||||
"closed": ""
|
||||
},
|
||||
"support": "",
|
||||
"moreOptions": "",
|
||||
"reactions": {
|
||||
@@ -142,13 +146,15 @@
|
||||
"participants": "",
|
||||
"effects": "",
|
||||
"chat": "",
|
||||
"transcript": ""
|
||||
"transcript": "",
|
||||
"admin": ""
|
||||
},
|
||||
"content": {
|
||||
"participants": "",
|
||||
"effects": "",
|
||||
"chat": "",
|
||||
"transcript": ""
|
||||
"transcript": "",
|
||||
"admin": ""
|
||||
},
|
||||
"closeButton": ""
|
||||
},
|
||||
@@ -167,6 +173,13 @@
|
||||
"button": ""
|
||||
}
|
||||
},
|
||||
"admin": {
|
||||
"description": "",
|
||||
"access": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"rating": {
|
||||
"submit": "",
|
||||
"question": "",
|
||||
|
||||
@@ -96,6 +96,10 @@
|
||||
"open": "Hide AI assistant",
|
||||
"closed": "Show AI assistant"
|
||||
},
|
||||
"admin": {
|
||||
"open": "Hide admin",
|
||||
"closed": "Open admin"
|
||||
},
|
||||
"support": "Support",
|
||||
"moreOptions": "More options",
|
||||
"reactions": {
|
||||
@@ -141,13 +145,15 @@
|
||||
"participants": "Participants",
|
||||
"effects": "Effects",
|
||||
"chat": "Messages in the chat",
|
||||
"transcript": "AI Assistant"
|
||||
"transcript": "AI Assistant",
|
||||
"admin": "Admin settings"
|
||||
},
|
||||
"content": {
|
||||
"participants": "participants",
|
||||
"effects": "effects",
|
||||
"chat": "messages",
|
||||
"transcript": "AI assistant"
|
||||
"transcript": "AI assistant",
|
||||
"admin": "Admin settings"
|
||||
},
|
||||
"closeButton": "Hide {{content}}"
|
||||
},
|
||||
@@ -166,6 +172,13 @@
|
||||
"button": "Stop Recording"
|
||||
}
|
||||
},
|
||||
"admin": {
|
||||
"description": "These organizer settings allow you to maintain control of your meeting. Only organizers can access these controls.",
|
||||
"access": {
|
||||
"title": "Room access",
|
||||
"description": "These settings will also apply to future occurrences of this meeting."
|
||||
}
|
||||
},
|
||||
"rating": {
|
||||
"submit": "Submit",
|
||||
"question": "What do you think about the quality of your call?",
|
||||
|
||||
@@ -96,6 +96,10 @@
|
||||
"open": "Masquer l'assistant IA",
|
||||
"closed": "Afficher l'assistant IA"
|
||||
},
|
||||
"admin": {
|
||||
"open": "Masquer l'admin",
|
||||
"closed": "Afficher l'admin"
|
||||
},
|
||||
"support": "Support",
|
||||
"moreOptions": "Plus d'options",
|
||||
"reactions": {
|
||||
@@ -141,13 +145,15 @@
|
||||
"participants": "Participants",
|
||||
"effects": "Effets",
|
||||
"chat": "Messages dans l'appel",
|
||||
"transcript": "Assistant IA"
|
||||
"transcript": "Assistant IA",
|
||||
"admin": "Commandes de l'organisateur"
|
||||
},
|
||||
"content": {
|
||||
"participants": "les participants",
|
||||
"effects": "les effets",
|
||||
"chat": "les messages",
|
||||
"transcript": "l'assistant IA"
|
||||
"transcript": "l'assistant IA",
|
||||
"admin": "Commandes de l'organisateur"
|
||||
},
|
||||
"closeButton": "Masquer {{content}}"
|
||||
},
|
||||
@@ -166,6 +172,13 @@
|
||||
"button": "Arrêter l'enregistrement"
|
||||
}
|
||||
},
|
||||
"admin": {
|
||||
"description": "Ces paramètres organisateur vous permettent de garder le contrôle de votre réunion. Seuls les organisateurs peuvent accéder à ces commandes.",
|
||||
"access": {
|
||||
"title": "Accès à la réunion",
|
||||
"description": "Ces paramètres s'appliqueront également aux futures occurences de cette réunion."
|
||||
}
|
||||
},
|
||||
"rating": {
|
||||
"submit": "Envoyer",
|
||||
"question": "Que pensez-vous de la qualité de votre appel ?",
|
||||
|
||||
Reference in New Issue
Block a user