Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

page.tsx 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. 'use client';
  2. import React from 'react';
  3. import PageTitle from '@/components/ui/PageTitle';
  4. import {
  5. EyeOutlined,
  6. EditOutlined,
  7. SortAscendingOutlined,
  8. PlusCircleFilled
  9. } from '@ant-design/icons';
  10. import type { Knowledge } from '@/types/knowledge';
  11. import { useRouter } from 'next/navigation';
  12. import { useQuery } from '@tanstack/react-query';
  13. import PrimaryButton from '@/components/ui/PrimaryButton';
  14. import { Flex, Row, Col, Tag, Button, Table, Layout, Image, Typography } from 'antd';
  15. import type { ColumnsType } from 'antd/es/table';
  16. import { getAllKnowledge } from '@/app/api/user/knowledgeService';
  17. import LoadingScreen from '@/components/layout/LoadingScreen';
  18. import { Persona } from '@/types/persona';
  19. const { Text, Title } = Typography;
  20. const columns: ColumnsType<Knowledge> = [
  21. {
  22. title: (
  23. <Text className="flex items-center gap-1">
  24. Knowledge Source <SortAscendingOutlined className="text-xs text-gray-400" />
  25. </Text>
  26. ),
  27. dataIndex: 'name',
  28. key: 'name'
  29. },
  30. {
  31. title: (
  32. <Text className="flex items-center gap-1">
  33. AI Persona <SortAscendingOutlined className="text-xs text-gray-400" />
  34. </Text>
  35. ),
  36. dataIndex: 'personas',
  37. key: 'personas',
  38. render: (record: Persona[]) => {
  39. if (record.length === 0) return '-';
  40. return (
  41. <Flex wrap>
  42. {record.map((persona) => (
  43. <Tag key={persona.id} color="blue">
  44. {persona.name}
  45. </Tag>
  46. ))}
  47. </Flex>
  48. );
  49. },
  50. },
  51. {
  52. title: 'Action',
  53. key: 'action',
  54. align: 'center' as const,
  55. render: () => (
  56. <Flex justify="center">
  57. <Button type="text" icon={<EditOutlined />} />
  58. <Button type="text" icon={<EyeOutlined />} />
  59. </Flex>
  60. ),
  61. },
  62. ]
  63. const Knowledge: React.FC = () => {
  64. const { data: knowledges, isLoading } = useQuery<Knowledge[]>({
  65. queryKey: ["getAllKnowledge"],
  66. queryFn: () => getAllKnowledge()
  67. })
  68. // Show loading state while fetching data
  69. if (isLoading) return <LoadingScreen/>
  70. if (!knowledges) {
  71. return <p></p>
  72. }
  73. return (
  74. <main className="flex flex-col bg-white h-full">
  75. <PageTitle>KNOWLEDGE SOURCES</PageTitle>
  76. {knowledges.length > 0 ? <KnowledgeList knowledgeData={knowledges} /> : <EmptyKnowledgeIntro />}
  77. </main>
  78. );
  79. };
  80. const EmptyKnowledgeIntro: React.FC = () => {
  81. const router = useRouter();
  82. return (
  83. <Flex vertical flex={1} justify="center" align="center">
  84. <Row justify="center" style={{ width: '100%', padding: '0 24px' }}>
  85. <Col xs={24} sm={20} md={16} lg={12} xl={8}>
  86. <Flex
  87. vertical
  88. align="center"
  89. className="!text-center"
  90. style={{
  91. border: '2px solid #06b6d4', // cyan-500
  92. borderRadius: 12,
  93. padding: '40px 24px',
  94. boxShadow: '0 10px 100px 30px rgba(59, 130, 246, 0.3)',
  95. background: '#fff',
  96. }}
  97. >
  98. <Title level={5} style={{ color: '#1f2937', marginBottom: 8 }}>
  99. NO SOURCE ADDED YET
  100. </Title>
  101. <Text type="secondary" style={{ marginBottom: 24 }}>
  102. Get started by adding your first knowledge source
  103. </Text>
  104. <Image
  105. src="/ruccan_logo2.png"
  106. alt="Ruccan Logo"
  107. width={150}
  108. preview={false}
  109. style={{ marginBottom: 24 }}
  110. />
  111. <PrimaryButton onClick={()=>{router.push("/user/knowledge/create")}}>
  112. ADD FIRST SOURCE
  113. </PrimaryButton>
  114. </Flex>
  115. </Col>
  116. </Row>
  117. </Flex>
  118. );
  119. };
  120. interface KnowledgeListProps {
  121. knowledgeData: Knowledge[] | undefined;
  122. }
  123. const KnowledgeList: React.FC<KnowledgeListProps> = ({ knowledgeData }) => {
  124. const router = useRouter();
  125. return (
  126. <Layout className="!overflow-x-auto">
  127. <Flex className='!px-2 !py-4 !justify-end'>
  128. <PrimaryButton onClick={() => { router.push('knowledge/create') }}>
  129. <PlusCircleFilled /> Add Source
  130. </PrimaryButton>
  131. </Flex>
  132. <Table
  133. className="[&_.ant-table-cell]:!p-2"
  134. rowKey="id"
  135. columns={columns}
  136. dataSource={knowledgeData}
  137. pagination={false}
  138. bordered
  139. />
  140. </Layout>
  141. );
  142. };
  143. export default Knowledge;