feat: add deals, tasks, and organizations pages with CRUD functionality
- Implemented DealsPage with deal creation, updating, and filtering features. - Added OrganizationsPage to manage and switch between organizations. - Created TasksPage for task management, including task creation and filtering. - Updated router to include new pages for navigation.
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import { Building2, RefreshCw } from 'lucide-react'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Skeleton } from '@/components/ui/skeleton'
|
||||
import { useToast } from '@/components/ui/use-toast'
|
||||
import { useOrganizationsQuery, useInvalidateOrganizations } from '@/features/organizations/hooks'
|
||||
import { useAuthStore } from '@/stores/auth-store'
|
||||
import { formatDate } from '@/lib/utils'
|
||||
|
||||
const OrganizationsPage = () => {
|
||||
const { data: organizations, isLoading, isFetching } = useOrganizationsQuery()
|
||||
const activeOrganizationId = useAuthStore((state) => state.activeOrganizationId)
|
||||
const setActiveOrganization = useAuthStore((state) => state.setActiveOrganization)
|
||||
const invalidate = useInvalidateOrganizations()
|
||||
const { toast } = useToast()
|
||||
|
||||
const handleSwitch = (id: number) => {
|
||||
setActiveOrganization(id)
|
||||
toast({ title: 'Контекст переключён', description: 'Все запросы теперь выполняются в выбранной организации.' })
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
|
||||
<div>
|
||||
<h1 className="text-2xl font-semibold text-foreground">Организации</h1>
|
||||
<p className="text-sm text-muted-foreground">Список компаний, к которым у вас есть доступ.</p>
|
||||
</div>
|
||||
<Button variant="outline" size="sm" className="gap-2" onClick={invalidate} disabled={isFetching}>
|
||||
<RefreshCw className={`h-4 w-4 ${isFetching ? 'animate-spin' : ''}`} />
|
||||
Обновить
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{isLoading ? (
|
||||
<div className="grid gap-4 lg:grid-cols-2">
|
||||
{[...Array(2)].map((_, index) => (
|
||||
<Card key={index} className="border-dashed">
|
||||
<CardHeader>
|
||||
<Skeleton className="h-4 w-32" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Skeleton className="h-6 w-24" />
|
||||
<Skeleton className="mt-4 h-4 w-40" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
) : organizations && organizations.length ? (
|
||||
<div className="grid gap-4 lg:grid-cols-2">
|
||||
{organizations.map((org) => (
|
||||
<Card key={org.id} className={org.id === activeOrganizationId ? 'border-primary shadow-md' : undefined}>
|
||||
<CardHeader className="flex flex-row items-center gap-3">
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-primary/10 text-primary">
|
||||
<Building2 className="h-5 w-5" />
|
||||
</div>
|
||||
<div>
|
||||
<CardTitle className="text-lg">{org.name}</CardTitle>
|
||||
<CardDescription>ID {org.id}</CardDescription>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">Создана {formatDate(org.created_at)}</p>
|
||||
{org.id === activeOrganizationId ? (
|
||||
<p className="text-sm font-medium text-primary">Активная организация</p>
|
||||
) : null}
|
||||
</div>
|
||||
{org.id === activeOrganizationId ? null : (
|
||||
<Button variant="outline" size="sm" onClick={() => handleSwitch(org.id)}>
|
||||
Сделать активной
|
||||
</Button>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<Card className="border-dashed text-center">
|
||||
<CardHeader>
|
||||
<CardTitle>Нет организаций</CardTitle>
|
||||
<CardDescription>Обратитесь к администратору, чтобы вас добавили в рабочую область.</CardDescription>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default OrganizationsPage
|
||||
Reference in New Issue
Block a user