Initial commit from monorepo

This commit is contained in:
Ruslan Bakiev
2026-01-07 09:10:35 +07:00
commit 3db50d9637
371 changed files with 43223 additions and 0 deletions

View File

@@ -0,0 +1,160 @@
<template>
<Section variant="plain">
<Stack gap="6">
<Stack gap="2">
<Heading :level="1">{{ $t('dashboard.switch_company') }}</Heading>
<Text tone="muted" size="base">{{ $t('teams.switch_description') }}</Text>
</Stack>
<Alert v-if="hasError" variant="error">
<Stack gap="2">
<Heading :level="4" weight="semibold">{{ $t('common.error') }}</Heading>
<Text tone="muted">{{ error }}</Text>
<Button @click="loadUserTeams">{{ t('clientTeam.error.retry') }}</Button>
</Stack>
</Alert>
<Card v-else-if="isLoading" tone="muted" padding="lg">
<Stack align="center" justify="center" gap="3">
<Spinner />
<Text tone="muted">{{ t('clientTeamSwitch.loading.message') }}</Text>
</Stack>
</Card>
<Card v-else-if="!userTeams.length && !showCreateForm" padding="lg">
<Stack align="center" gap="3">
<IconCircle tone="primary">🏢</IconCircle>
<Heading :level="3" align="center">{{ $t('teams.no_team') }}</Heading>
<Text tone="muted" align="center">{{ $t('teams.no_team_description') }}</Text>
<Button @click="showCreateForm = true">
{{ $t('teams.create_first_team') }}
</Button>
</Stack>
</Card>
<template v-else>
<Grid :cols="1" :md="2" :lg="3" :gap="4" v-if="!showCreateForm">
<Card
v-for="team in userTeams"
:key="team.id"
padding="lg"
:class="[
'cursor-pointer transition-all',
team.isActive ? 'ring-2 ring-primary bg-primary/5' : 'hover:shadow-md'
]"
@click="switchToTeam(team.id)"
>
<Stack gap="3">
<Stack direction="row" gap="3" align="center">
<IconCircle :tone="team.isActive ? 'primary' : 'neutral'">
{{ team.name?.charAt(0)?.toUpperCase() || '?' }}
</IconCircle>
<Stack gap="1">
<Heading :level="4" weight="semibold">{{ team.name }}</Heading>
</Stack>
</Stack>
<Pill v-if="team.isActive" variant="primary">{{ $t('teams.active') }}</Pill>
</Stack>
</Card>
<Card padding="lg" class="border-2 border-dashed border-base-300 hover:border-primary cursor-pointer transition-colors" @click="showCreateForm = true">
<Stack align="center" gap="3">
<IconCircle tone="neutral"></IconCircle>
<Heading :level="4" weight="semibold">{{ $t('teams.create_new_team') }}</Heading>
<Text tone="muted" align="center">{{ $t('teams.create_description') }}</Text>
</Stack>
</Card>
</Grid>
<TeamCreateForm
v-else
@team-created="handleTeamCreated"
@cancel="showCreateForm = false"
/>
</template>
</Stack>
</Section>
</template>
<script setup lang="ts">
import { SwitchTeamDocument } from '~/composables/graphql/user/teams-generated'
definePageMeta({
middleware: ['auth-oidc']
})
const localePath = useLocalePath()
const { t } = useI18n()
const { mutate } = useGraphQL()
const { setActiveTeam } = useActiveTeam()
const me = useState<{
teams?: Array<{ id?: string | null; name: string; logtoOrgId?: string | null } | null> | null
activeTeamId?: string | null
} | null>('me', () => null)
const userTeams = ref<Array<{ id: string; name: string; logtoOrgId?: string | null; isActive?: boolean }>>([])
const isLoading = ref(true)
const hasError = ref(false)
const error = ref('')
const showCreateForm = ref(false)
const currentActiveTeam = computed(() => userTeams.value.find(team => team.isActive) || null)
const otherTeams = computed(() => userTeams.value.filter(team => !team.isActive))
const markActiveTeam = (teamId: string) => {
if (me.value) {
me.value = { ...me.value, activeTeamId: teamId }
}
userTeams.value = userTeams.value.map(team => ({
...team,
isActive: team.id === teamId
}))
}
const loadUserTeams = () => {
isLoading.value = true
hasError.value = false
if (!me.value?.teams) {
hasError.value = true
error.value = t('clientTeamSwitch.error.load')
isLoading.value = false
return
}
userTeams.value = me.value.teams
.filter((t): t is NonNullable<typeof t> => t !== null)
.map(t => ({
id: t.id || '',
name: t.name,
logtoOrgId: t.logtoOrgId,
isActive: t.id === me.value?.activeTeamId
}))
isLoading.value = false
}
const switchToTeam = async (teamId: string) => {
try {
const selectedTeam = userTeams.value.find(team => team.id === teamId)
if (selectedTeam) setActiveTeam(teamId, selectedTeam.logtoOrgId)
const result = await mutate(SwitchTeamDocument, { teamId }, 'user', 'teams')
if (result.switchTeam?.user) {
const newActiveId = result.switchTeam.user.activeTeamId || teamId
setActiveTeam(newActiveId, selectedTeam?.logtoOrgId)
markActiveTeam(newActiveId)
navigateTo(localePath('/clientarea/team'))
}
} catch (err: any) {
error.value = err.message || t('clientTeamSwitch.error.switch')
hasError.value = true
}
}
const handleTeamCreated = () => {
showCreateForm.value = false
navigateTo(localePath('/clientarea/team'))
}
loadUserTeams()
</script>