added graphql entegration and tested tanstack query

This commit is contained in:
2025-11-15 16:37:51 +03:00
parent a67170daa8
commit cf4f632afe
526 changed files with 55717 additions and 154 deletions

View File

@@ -0,0 +1,61 @@
'use server';
import { NextResponse } from 'next/server';
import { GraphQLClient, gql } from 'graphql-request';
const endpoint = process.env.GRAPHQL_URL || "http://localhost:3001/graphql";
export async function POST(request: Request) {
const body = await request.json();
const { limit, skip, sort, filters } = body;
try {
const client = new GraphQLClient(endpoint);
const query = gql`
query ListUsers($input: ListArguments!) {
users(input: $input) {
data {
_id
uuid
expiryStarts
expiryEnds
isConfirmed
deleted
active
crypUuId
createdCredentialsToken
updatedCredentialsToken
confirmedCredentialsToken
isNotificationSend
isEmailSend
refInt
refId
replicationId
expiresAt
resetToken
password
history
tag
email
phone
collectionTokens {
default
tokens {
prefix
token
}
}
createdAt
updatedAt
}
totalCount
}
}
`;
console.dir({ limit, skip, sort, filters }, { depth: null });
const variables = { input: { limit, skip, sort, filters } };
const data = await client.request(query, variables);
return NextResponse.json({ data: data.users.data, totalCount: data.users.totalCount });
} catch (err: any) {
console.error(err);
return NextResponse.json({ error: err.message }, { status: 500 });
}
}

View File

@@ -0,0 +1,5 @@
import DashboardPage from "@/pages/dashboard/page";
const PageDashboard = () => { return <DashboardPage /> };
export default PageDashboard;

View File

@@ -0,0 +1,10 @@
const PeoplePage = () => {
return (
<div>
<h1>People</h1>
</div>
)
}
export default PeoplePage;

View File

@@ -0,0 +1,5 @@
import { PageUsers } from "@/pages/users/page";
const UserPage = () => { return <><PageUsers /></> }
export default UserPage;

View File

@@ -19,10 +19,10 @@ import {
IconUsers,
} from "@tabler/icons-react"
import { NavMain } from "@/frontend/components/dashboard/nav-main"
import { NavSecondary } from "@/frontend/components/dashboard/nav-secondary"
import { NavUser } from "@/frontend/components/dashboard/nav-user"
import { NavDocuments } from "@/frontend/components/dashboard/nav-documents"
import { NavMain } from "@/components/dashboard/nav-main"
import { NavSecondary } from "@/components/dashboard/nav-secondary"
import { NavUser } from "@/components/dashboard/nav-user"
import { NavDocuments } from "@/components/dashboard/nav-documents"
import {
Sidebar,
@@ -32,7 +32,7 @@ import {
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/frontend/components/ui/sidebar"
} from "@/components/ui/sidebar"
const data = {
user: {

View File

@@ -11,24 +11,24 @@ import {
CardDescription,
CardHeader,
CardTitle,
} from "@/frontend/components/ui/card"
} from "@/components/ui/card"
import {
ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/frontend/components/ui/chart"
} from "@/components/ui/chart"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/frontend/components/ui/select"
} from "@/components/ui/select"
import {
ToggleGroup,
ToggleGroupItem,
} from "@/frontend/components/ui/toggle-group"
} from "@/components/ui/toggle-group"
export const description = "An interactive area chart"

View File

@@ -54,15 +54,15 @@ import { toast } from "sonner"
import { z } from "zod"
import { useIsMobile } from "@/hooks/use-mobile"
import { Badge } from "@/frontend/components/ui/badge"
import { Button } from "@/frontend/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import {
ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/frontend/components/ui/chart"
import { Checkbox } from "@/frontend/components/ui/checkbox"
} from "@/components/ui/chart"
import { Checkbox } from "@/components/ui/checkbox"
import {
Drawer,
DrawerClose,
@@ -72,7 +72,7 @@ import {
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from "@/frontend/components/ui/drawer"
} from "@/components/ui/drawer"
import {
DropdownMenu,
DropdownMenuCheckboxItem,
@@ -80,17 +80,17 @@ import {
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/frontend/components/ui/dropdown-menu"
import { Input } from "@/frontend/components/ui/input"
import { Label } from "@/frontend/components/ui/label"
} from "@/components/ui/dropdown-menu"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/frontend/components/ui/select"
import { Separator } from "@/frontend/components/ui/separator"
} from "@/components/ui/select"
import { Separator } from "@/components/ui/separator"
import {
Table,
TableBody,
@@ -98,13 +98,13 @@ import {
TableHead,
TableHeader,
TableRow,
} from "@/frontend/components/ui/table"
} from "@/components/ui/table"
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from "@/frontend/components/ui/tabs"
} from "@/components/ui/tabs"
export const schema = z.object({
id: z.number(),

View File

@@ -14,7 +14,7 @@ import {
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/frontend/components/ui/dropdown-menu"
} from "@/components/ui/dropdown-menu"
import {
SidebarGroup,
SidebarGroupLabel,
@@ -23,7 +23,7 @@ import {
SidebarMenuButton,
SidebarMenuItem,
useSidebar,
} from "@/frontend/components/ui/sidebar"
} from "@/components/ui/sidebar"
export function NavDocuments({
items,

View File

@@ -2,14 +2,14 @@
import { IconCirclePlusFilled, IconMail, type Icon } from "@tabler/icons-react"
import { Button } from "@/frontend/components/ui/button"
import { Button } from "@/components/ui/button"
import {
SidebarGroup,
SidebarGroupContent,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/frontend/components/ui/sidebar"
} from "@/components/ui/sidebar"
export function NavMain({
items,

View File

@@ -9,7 +9,7 @@ import {
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/frontend/components/ui/sidebar"
} from "@/components/ui/sidebar"
export function NavSecondary({
items,

View File

@@ -12,7 +12,7 @@ import {
Avatar,
AvatarFallback,
AvatarImage,
} from "@/frontend/components/ui/avatar"
} from "@/components/ui/avatar"
import {
DropdownMenu,
DropdownMenuContent,
@@ -21,13 +21,13 @@ import {
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/frontend/components/ui/dropdown-menu"
} from "@/components/ui/dropdown-menu"
import {
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
useSidebar,
} from "@/frontend/components/ui/sidebar"
} from "@/components/ui/sidebar"
export function NavUser({
user,

View File

@@ -1,6 +1,6 @@
import { IconTrendingDown, IconTrendingUp } from "@tabler/icons-react"
import { Badge } from "@/frontend/components/ui/badge"
import { Badge } from "@/components/ui/badge"
import {
Card,
CardAction,
@@ -8,7 +8,7 @@ import {
CardFooter,
CardHeader,
CardTitle,
} from "@/frontend/components/ui/card"
} from "@/components/ui/card"
export function SectionCards() {
return (

View File

@@ -1,6 +1,6 @@
import { Button } from "@/frontend/components/ui/button"
import { Separator } from "@/frontend/components/ui/separator"
import { SidebarTrigger } from "@/frontend/components/ui/sidebar"
import { Button } from "@/components/ui/button"
import { Separator } from "@/components/ui/separator"
import { SidebarTrigger } from "@/components/ui/sidebar"
export function SiteHeader() {
return (

View File

@@ -7,23 +7,23 @@ import { PanelLeftIcon } from "lucide-react"
import { useIsMobile } from "@/hooks/use-mobile"
import { cn } from "@/lib/utils"
import { Button } from "@/frontend/components/ui/button"
import { Input } from "@/frontend/components/ui/input"
import { Separator } from "@/frontend/components/ui/separator"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Separator } from "@/components/ui/separator"
import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
} from "@/frontend/components/ui/sheet"
import { Skeleton } from "@/frontend/components/ui/skeleton"
} from "@/components/ui/sheet"
import { Skeleton } from "@/components/ui/skeleton"
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/frontend/components/ui/tooltip"
} from "@/components/ui/tooltip"
const SIDEBAR_COOKIE_NAME = "sidebar_state"
const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7

View File

@@ -5,7 +5,7 @@ import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"
import { type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
import { toggleVariants } from "@/frontend/components/ui/toggle"
import { toggleVariants } from "@/components/ui/toggle"
const ToggleGroupContext = React.createContext<
VariantProps<typeof toggleVariants> & {

View File

@@ -28,6 +28,8 @@
"@tanstack/react-table": "^8.21.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"graphql-request": "^7.3.3",
"graphql-type-json": "^0.3.2",
"lucide-react": "^0.553.0",
"next": "16.0.2",
"next-auth": "^4.24.7",
@@ -37,7 +39,8 @@
"recharts": "^2.15.4",
"sonner": "^2.0.7",
"tailwind-merge": "^3.4.0",
"vaul": "^1.1.2"
"vaul": "^1.1.2",
"zod": "^4.1.12"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
@@ -597,6 +600,15 @@
"integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==",
"license": "MIT"
},
"node_modules/@graphql-typed-document-node/core": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz",
"integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==",
"license": "MIT",
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
@@ -5942,6 +5954,37 @@
"dev": true,
"license": "MIT"
},
"node_modules/graphql": {
"version": "16.12.0",
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.12.0.tgz",
"integrity": "sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
}
},
"node_modules/graphql-request": {
"version": "7.3.3",
"resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-7.3.3.tgz",
"integrity": "sha512-I0ZSz53XTpDiQZ0/KGElwfnzIqsdNek/D6tcZgheL8QOVeSbkgE3qG7r1G/MKtnNenWtEjHbsDf2iPlXSWxFtw==",
"license": "MIT",
"dependencies": {
"@graphql-typed-document-node/core": "^3.2.0"
},
"peerDependencies": {
"graphql": "14 - 16"
}
},
"node_modules/graphql-type-json": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.3.2.tgz",
"integrity": "sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg==",
"license": "MIT",
"peerDependencies": {
"graphql": ">=0.8.0"
}
},
"node_modules/has-bigints": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
@@ -9116,7 +9159,6 @@
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz",
"integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==",
"dev": true,
"license": "MIT",
"peer": true,
"funding": {

View File

@@ -29,6 +29,8 @@
"@tanstack/react-table": "^8.21.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"graphql-request": "^7.3.3",
"graphql-type-json": "^0.3.2",
"lucide-react": "^0.553.0",
"next": "16.0.2",
"next-auth": "^4.24.7",
@@ -38,7 +40,8 @@
"recharts": "^2.15.4",
"sonner": "^2.0.7",
"tailwind-merge": "^3.4.0",
"vaul": "^1.1.2"
"vaul": "^1.1.2",
"zod": "^4.1.12"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
@@ -51,4 +54,4 @@
"tw-animate-css": "^1.4.0",
"typescript": "^5"
}
}
}

View File

View File

@@ -0,0 +1,614 @@
[
{
"id": 1,
"header": "Cover page",
"type": "Cover page",
"status": "In Process",
"target": "18",
"limit": "5",
"reviewer": "Eddie Lake"
},
{
"id": 2,
"header": "Table of contents",
"type": "Table of contents",
"status": "Done",
"target": "29",
"limit": "24",
"reviewer": "Eddie Lake"
},
{
"id": 3,
"header": "Executive summary",
"type": "Narrative",
"status": "Done",
"target": "10",
"limit": "13",
"reviewer": "Eddie Lake"
},
{
"id": 4,
"header": "Technical approach",
"type": "Narrative",
"status": "Done",
"target": "27",
"limit": "23",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 5,
"header": "Design",
"type": "Narrative",
"status": "In Process",
"target": "2",
"limit": "16",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 6,
"header": "Capabilities",
"type": "Narrative",
"status": "In Process",
"target": "20",
"limit": "8",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 7,
"header": "Integration with existing systems",
"type": "Narrative",
"status": "In Process",
"target": "19",
"limit": "21",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 8,
"header": "Innovation and Advantages",
"type": "Narrative",
"status": "Done",
"target": "25",
"limit": "26",
"reviewer": "Assign reviewer"
},
{
"id": 9,
"header": "Overview of EMR's Innovative Solutions",
"type": "Technical content",
"status": "Done",
"target": "7",
"limit": "23",
"reviewer": "Assign reviewer"
},
{
"id": 10,
"header": "Advanced Algorithms and Machine Learning",
"type": "Narrative",
"status": "Done",
"target": "30",
"limit": "28",
"reviewer": "Assign reviewer"
},
{
"id": 11,
"header": "Adaptive Communication Protocols",
"type": "Narrative",
"status": "Done",
"target": "9",
"limit": "31",
"reviewer": "Assign reviewer"
},
{
"id": 12,
"header": "Advantages Over Current Technologies",
"type": "Narrative",
"status": "Done",
"target": "12",
"limit": "0",
"reviewer": "Assign reviewer"
},
{
"id": 13,
"header": "Past Performance",
"type": "Narrative",
"status": "Done",
"target": "22",
"limit": "33",
"reviewer": "Assign reviewer"
},
{
"id": 14,
"header": "Customer Feedback and Satisfaction Levels",
"type": "Narrative",
"status": "Done",
"target": "15",
"limit": "34",
"reviewer": "Assign reviewer"
},
{
"id": 15,
"header": "Implementation Challenges and Solutions",
"type": "Narrative",
"status": "Done",
"target": "3",
"limit": "35",
"reviewer": "Assign reviewer"
},
{
"id": 16,
"header": "Security Measures and Data Protection Policies",
"type": "Narrative",
"status": "In Process",
"target": "6",
"limit": "36",
"reviewer": "Assign reviewer"
},
{
"id": 17,
"header": "Scalability and Future Proofing",
"type": "Narrative",
"status": "Done",
"target": "4",
"limit": "37",
"reviewer": "Assign reviewer"
},
{
"id": 18,
"header": "Cost-Benefit Analysis",
"type": "Plain language",
"status": "Done",
"target": "14",
"limit": "38",
"reviewer": "Assign reviewer"
},
{
"id": 19,
"header": "User Training and Onboarding Experience",
"type": "Narrative",
"status": "Done",
"target": "17",
"limit": "39",
"reviewer": "Assign reviewer"
},
{
"id": 20,
"header": "Future Development Roadmap",
"type": "Narrative",
"status": "Done",
"target": "11",
"limit": "40",
"reviewer": "Assign reviewer"
},
{
"id": 21,
"header": "System Architecture Overview",
"type": "Technical content",
"status": "In Process",
"target": "24",
"limit": "18",
"reviewer": "Maya Johnson"
},
{
"id": 22,
"header": "Risk Management Plan",
"type": "Narrative",
"status": "Done",
"target": "15",
"limit": "22",
"reviewer": "Carlos Rodriguez"
},
{
"id": 23,
"header": "Compliance Documentation",
"type": "Legal",
"status": "In Process",
"target": "31",
"limit": "27",
"reviewer": "Sarah Chen"
},
{
"id": 24,
"header": "API Documentation",
"type": "Technical content",
"status": "Done",
"target": "8",
"limit": "12",
"reviewer": "Raj Patel"
},
{
"id": 25,
"header": "User Interface Mockups",
"type": "Visual",
"status": "In Process",
"target": "19",
"limit": "25",
"reviewer": "Leila Ahmadi"
},
{
"id": 26,
"header": "Database Schema",
"type": "Technical content",
"status": "Done",
"target": "22",
"limit": "20",
"reviewer": "Thomas Wilson"
},
{
"id": 27,
"header": "Testing Methodology",
"type": "Technical content",
"status": "In Process",
"target": "17",
"limit": "14",
"reviewer": "Assign reviewer"
},
{
"id": 28,
"header": "Deployment Strategy",
"type": "Narrative",
"status": "Done",
"target": "26",
"limit": "30",
"reviewer": "Eddie Lake"
},
{
"id": 29,
"header": "Budget Breakdown",
"type": "Financial",
"status": "In Process",
"target": "13",
"limit": "16",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 30,
"header": "Market Analysis",
"type": "Research",
"status": "Done",
"target": "29",
"limit": "32",
"reviewer": "Sophia Martinez"
},
{
"id": 31,
"header": "Competitor Comparison",
"type": "Research",
"status": "In Process",
"target": "21",
"limit": "19",
"reviewer": "Assign reviewer"
},
{
"id": 32,
"header": "Maintenance Plan",
"type": "Technical content",
"status": "Done",
"target": "16",
"limit": "23",
"reviewer": "Alex Thompson"
},
{
"id": 33,
"header": "User Personas",
"type": "Research",
"status": "In Process",
"target": "27",
"limit": "24",
"reviewer": "Nina Patel"
},
{
"id": 34,
"header": "Accessibility Compliance",
"type": "Legal",
"status": "Done",
"target": "18",
"limit": "21",
"reviewer": "Assign reviewer"
},
{
"id": 35,
"header": "Performance Metrics",
"type": "Technical content",
"status": "In Process",
"target": "23",
"limit": "26",
"reviewer": "David Kim"
},
{
"id": 36,
"header": "Disaster Recovery Plan",
"type": "Technical content",
"status": "Done",
"target": "14",
"limit": "17",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 37,
"header": "Third-party Integrations",
"type": "Technical content",
"status": "In Process",
"target": "25",
"limit": "28",
"reviewer": "Eddie Lake"
},
{
"id": 38,
"header": "User Feedback Summary",
"type": "Research",
"status": "Done",
"target": "20",
"limit": "15",
"reviewer": "Assign reviewer"
},
{
"id": 39,
"header": "Localization Strategy",
"type": "Narrative",
"status": "In Process",
"target": "12",
"limit": "19",
"reviewer": "Maria Garcia"
},
{
"id": 40,
"header": "Mobile Compatibility",
"type": "Technical content",
"status": "Done",
"target": "28",
"limit": "31",
"reviewer": "James Wilson"
},
{
"id": 41,
"header": "Data Migration Plan",
"type": "Technical content",
"status": "In Process",
"target": "19",
"limit": "22",
"reviewer": "Assign reviewer"
},
{
"id": 42,
"header": "Quality Assurance Protocols",
"type": "Technical content",
"status": "Done",
"target": "30",
"limit": "33",
"reviewer": "Priya Singh"
},
{
"id": 43,
"header": "Stakeholder Analysis",
"type": "Research",
"status": "In Process",
"target": "11",
"limit": "14",
"reviewer": "Eddie Lake"
},
{
"id": 44,
"header": "Environmental Impact Assessment",
"type": "Research",
"status": "Done",
"target": "24",
"limit": "27",
"reviewer": "Assign reviewer"
},
{
"id": 45,
"header": "Intellectual Property Rights",
"type": "Legal",
"status": "In Process",
"target": "17",
"limit": "20",
"reviewer": "Sarah Johnson"
},
{
"id": 46,
"header": "Customer Support Framework",
"type": "Narrative",
"status": "Done",
"target": "22",
"limit": "25",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 47,
"header": "Version Control Strategy",
"type": "Technical content",
"status": "In Process",
"target": "15",
"limit": "18",
"reviewer": "Assign reviewer"
},
{
"id": 48,
"header": "Continuous Integration Pipeline",
"type": "Technical content",
"status": "Done",
"target": "26",
"limit": "29",
"reviewer": "Michael Chen"
},
{
"id": 49,
"header": "Regulatory Compliance",
"type": "Legal",
"status": "In Process",
"target": "13",
"limit": "16",
"reviewer": "Assign reviewer"
},
{
"id": 50,
"header": "User Authentication System",
"type": "Technical content",
"status": "Done",
"target": "28",
"limit": "31",
"reviewer": "Eddie Lake"
},
{
"id": 51,
"header": "Data Analytics Framework",
"type": "Technical content",
"status": "In Process",
"target": "21",
"limit": "24",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 52,
"header": "Cloud Infrastructure",
"type": "Technical content",
"status": "Done",
"target": "16",
"limit": "19",
"reviewer": "Assign reviewer"
},
{
"id": 53,
"header": "Network Security Measures",
"type": "Technical content",
"status": "In Process",
"target": "29",
"limit": "32",
"reviewer": "Lisa Wong"
},
{
"id": 54,
"header": "Project Timeline",
"type": "Planning",
"status": "Done",
"target": "14",
"limit": "17",
"reviewer": "Eddie Lake"
},
{
"id": 55,
"header": "Resource Allocation",
"type": "Planning",
"status": "In Process",
"target": "27",
"limit": "30",
"reviewer": "Assign reviewer"
},
{
"id": 56,
"header": "Team Structure and Roles",
"type": "Planning",
"status": "Done",
"target": "20",
"limit": "23",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 57,
"header": "Communication Protocols",
"type": "Planning",
"status": "In Process",
"target": "15",
"limit": "18",
"reviewer": "Assign reviewer"
},
{
"id": 58,
"header": "Success Metrics",
"type": "Planning",
"status": "Done",
"target": "30",
"limit": "33",
"reviewer": "Eddie Lake"
},
{
"id": 59,
"header": "Internationalization Support",
"type": "Technical content",
"status": "In Process",
"target": "23",
"limit": "26",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 60,
"header": "Backup and Recovery Procedures",
"type": "Technical content",
"status": "Done",
"target": "18",
"limit": "21",
"reviewer": "Assign reviewer"
},
{
"id": 61,
"header": "Monitoring and Alerting System",
"type": "Technical content",
"status": "In Process",
"target": "25",
"limit": "28",
"reviewer": "Daniel Park"
},
{
"id": 62,
"header": "Code Review Guidelines",
"type": "Technical content",
"status": "Done",
"target": "12",
"limit": "15",
"reviewer": "Eddie Lake"
},
{
"id": 63,
"header": "Documentation Standards",
"type": "Technical content",
"status": "In Process",
"target": "27",
"limit": "30",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 64,
"header": "Release Management Process",
"type": "Planning",
"status": "Done",
"target": "22",
"limit": "25",
"reviewer": "Assign reviewer"
},
{
"id": 65,
"header": "Feature Prioritization Matrix",
"type": "Planning",
"status": "In Process",
"target": "19",
"limit": "22",
"reviewer": "Emma Davis"
},
{
"id": 66,
"header": "Technical Debt Assessment",
"type": "Technical content",
"status": "Done",
"target": "24",
"limit": "27",
"reviewer": "Eddie Lake"
},
{
"id": 67,
"header": "Capacity Planning",
"type": "Planning",
"status": "In Process",
"target": "21",
"limit": "24",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 68,
"header": "Service Level Agreements",
"type": "Legal",
"status": "Done",
"target": "26",
"limit": "29",
"reviewer": "Assign reviewer"
}
]

View File

@@ -1,16 +1,16 @@
import { AppSidebar } from "@/components/app-sidebar"
import { ChartAreaInteractive } from "@/components/chart-area-interactive"
import { DataTable } from "@/components/data-table"
import { SectionCards } from "@/components/section-cards"
import { SiteHeader } from "@/components/site-header"
import { AppSidebar } from "@/components/dashboard/app-sidebar"
import { ChartAreaInteractive } from "@/components/dashboard/chart-area-interactive"
import { DataTable } from "@/components/dashboard/data-table"
import { SectionCards } from "@/components/dashboard/section-cards"
import { SiteHeader } from "@/components/dashboard/site-header"
import {
SidebarInset,
SidebarProvider,
} from "@/frontend/components/ui/sidebar"
} from "@/components/ui/sidebar"
import data from "./data.json"
export default function Page() {
export default function DashboardPage() {
return (
<SidebarProvider
style={

View File

@@ -0,0 +1,26 @@
'use client';
import { useGraphQlUsersList } from './queries';
import { useState } from 'react';
const PageUsers = () => {
const [page, setPage] = useState(1);
const [limit, setLimit] = useState(10);
const [sort, setSort] = useState({ createdAt: 'desc' });
const [filters, setFilters] = useState({});
const { data, isLoading, error } = useGraphQlUsersList({ limit, skip: (page - 1) * limit, sort, filters });
return (
<div>
<h1>Users</h1>
{isLoading && <p>Loading...</p>}
{error && <p>Error: {error.message}</p>}
{data && <p>Total count: {data.totalCount}</p>}
<div>
{data && <p>Data: {JSON.stringify(data.data)}</p>}
<button onClick={() => setPage(page - 1)}>Previous</button>
<button onClick={() => setPage(page + 1)}>Next</button>
</div>
</div>
)
}
export { PageUsers };

View File

@@ -0,0 +1,19 @@
'use client'
import { useQuery } from '@tanstack/react-query'
import { UsersListResponse } from './types'
import { ListArguments } from '@/types/listRequest'
const fetchGraphQlUsersList = async (params: ListArguments): Promise<UsersListResponse> => {
console.log('Fetching test data from local API');
const { limit, skip, sort, filters } = params;
try {
const res = await fetch('/api/users/list', { method: 'POST', cache: 'no-store', credentials: "include", body: JSON.stringify({ limit, skip, sort, filters }) });
if (!res.ok) { const errorText = await res.text(); console.error('Test data API error:', errorText); throw new Error(`API error: ${res.status} ${res.statusText}`) }
const data = await res.json();
return { data: data.data, totalCount: data.totalCount }
} catch (error) { console.error('Error fetching test data:', error); throw error }
};
export function useGraphQlUsersList(params: ListArguments) {
return useQuery({ queryKey: ['graphql-users-list', params], queryFn: () => fetchGraphQlUsersList(params) })
}

View File

@@ -0,0 +1,46 @@
interface UserToken {
prefix: string;
token: string;
}
interface CollectionTokens {
default: string;
tokens: UserToken[];
}
interface User {
_id: string;
uuid: string;
expiryStarts: string;
expiryEnds: string;
isConfirmed: boolean;
deleted: boolean;
active: boolean;
crypUuId: string;
createdCredentialsToken: string;
updatedCredentialsToken: string;
confirmedCredentialsToken: string;
isNotificationSend: boolean;
isEmailSend: boolean;
refInt: number;
refId: string;
replicationId: number;
expiresAt: string;
resetToken?: string | null;
password: string;
history: string[];
tag: string;
email: string;
phone: string;
collectionTokens: CollectionTokens;
createdAt: string;
updatedAt: string;
}
interface UsersListResponse {
data: User[] | null;
totalCount: number;
}
export type { User, UsersListResponse }

View File

@@ -24,7 +24,7 @@
],
"paths": {
"@/*": [
"./frontend/*"
"./*"
]
}
},
@@ -35,8 +35,10 @@
"frontend/.next/types/**/*.ts",
"frontend/.next/dev/types/**/*.ts",
"**/*.mts",
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}
}

View File

@@ -0,0 +1,8 @@
interface ListArguments {
filters?: Record<string, any>;
sort?: Record<string, any>;
skip: number;
limit: number;
}
export type { ListArguments };