You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

page.tsx 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. 'use client';
  2. import React, {useEffect, useState} 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 { Persona } from '@/types/persona';
  11. import { getPersona } from '@/app/api/user/personaService';
  12. import { useQuery } from '@tanstack/react-query';
  13. interface PersonaListProps {
  14. personaData: Persona[] | undefined;
  15. }
  16. const PersonaPage: React.FC = () => {
  17. let {data:personas, error, isLoading} = useQuery<Persona[]>({
  18. queryKey:["getPersona"],
  19. queryFn: () => getPersona()
  20. })
  21. if(isLoading) {
  22. return <p>Loading...</p>
  23. }
  24. if(!personas) {
  25. return <p></p>
  26. }
  27. return (
  28. <main className="flex flex-col bg-white h-full">
  29. <PageTitle title="PERSONA" />
  30. {(personas.length > 0) ? <PersonaList personaData={personas} /> : <PersonaIntro />}
  31. </main>
  32. );
  33. };
  34. const PersonaIntro: React.FC = () => {
  35. return (
  36. <div className="flex flex-col px-6 flex-1 justify-center items-center">
  37. <div
  38. className="w-full max-w-md text-center border-2 border-cyan-500 rounded-lg px-6 py-10 shadow-lg"
  39. style={{ boxShadow: '0 10px 100px 30px rgba(59, 130, 246, 0.3)' }} // red-500 with opacity
  40. >
  41. <p className="text-lg font-semibold mb-2 text-gray-800">NO PERSONA CREATED YET</p>
  42. <p className="text-sm text-gray-600 mb-4">Get started by creating your first AI Persona</p>
  43. <img
  44. src="/ruccan_logo.png"
  45. alt="Ruccan Logo"
  46. className="mx-auto mb-6"
  47. width={150}
  48. height={150}
  49. />
  50. <button className="w-fit rounded text-xs px-4 py-2 bg-[#369cc1] hover:bg-[#82c7d7] cursor-pointer text-white font-bold shadow transition-all duration-200">
  51. CREATE YOUR FIRST PERSONA
  52. </button>
  53. </div>
  54. </div>
  55. )
  56. }
  57. const PersonaList: React.FC<PersonaListProps> = ({personaData}) => {
  58. return (
  59. <div className="overflow-x-auto">
  60. <div className='flex px-2 py-4'>
  61. <button className="w-fit rounded text-xs px-4 py-2 bg-[#369cc1] hover:bg-[#82c7d7] cursor-pointer text-white font-bold shadow transition-all duration-200 ms-auto">
  62. <PlusCircleFilled /> Create New Persona
  63. </button>
  64. </div>
  65. <table className="w-full text-sm text-left text-gray-700 border-collapse">
  66. <thead>
  67. <tr className="bg-gray-100 text-gray-700">
  68. <th className="px-4 py-3 font-medium">
  69. <div className="flex items-center gap-1">
  70. Name <SortAscendingOutlined className="text-xs text-gray-400" />
  71. </div>
  72. </th>
  73. <th className="px-4 py-3 font-medium">
  74. <div className="flex items-center gap-1">
  75. Role <SortAscendingOutlined className="text-xs text-gray-400" />
  76. </div>
  77. </th>
  78. <th className="px-4 py-3 font-medium">
  79. <div className="flex items-center gap-1">
  80. Status <SortAscendingOutlined className="text-xs text-gray-400" />
  81. </div>
  82. </th>
  83. <th className="px-4 py-3 font-medium text-center">Action</th>
  84. </tr>
  85. </thead>
  86. <tbody>
  87. {personaData?.map((persona) => (
  88. <tr key={persona.id} className="border-t border-gray-200 hover:bg-gray-50">
  89. <td className="px-4 py-3">{persona.name}</td>
  90. <td className="px-4 py-3">{persona.role}</td>
  91. <td className="px-4 py-3">
  92. <span
  93. className={`px-2 py-1 rounded-full text-xs font-semibold ${persona.active
  94. ? 'bg-green-100 text-green-600'
  95. : 'bg-amber-600 text-white'
  96. }`}
  97. >
  98. {persona.active ? 'Active' : 'Inactive'}
  99. </span>
  100. </td>
  101. <td className="px-4 py-3 text-center">
  102. <div className="flex justify-center items-center gap-3 text-gray-600">
  103. <button
  104. className="hover:text-blue-500"
  105. aria-label="Edit"
  106. title="Edit"
  107. >
  108. <EditOutlined />
  109. </button>
  110. <button
  111. className="hover:text-green-600"
  112. aria-label="View"
  113. title="View"
  114. >
  115. <EyeOutlined />
  116. </button>
  117. </div>
  118. </td>
  119. </tr>
  120. ))}
  121. </tbody>
  122. </table>
  123. </div>
  124. );
  125. };
  126. export default PersonaPage;