index.tsx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. 'use client'
  2. import React, { useState } from 'react'
  3. import useSWR from 'swr'
  4. import {
  5. ChevronDownIcon,
  6. ChevronUpIcon,
  7. } from '@heroicons/react/24/outline'
  8. import { fetchHistories } from '@/models/history'
  9. import type { History as HistoryItem } from '@/models/history'
  10. import Loading from '@/app/components/base/loading'
  11. import { mockAPI } from '@/test/test_util'
  12. mockAPI()
  13. export type IHistoryProps = {
  14. dictionary: any
  15. }
  16. const HistoryCard = (
  17. { history }: { history: HistoryItem },
  18. ) => {
  19. return (
  20. <div className='p-4 h-32 bg-gray-50 border-gray-200 rounded-lg relative flex flex-col justify-between items-center cursor-pointer'>
  21. <div className='text-gray-700 text-sm'>
  22. {history.source}
  23. </div>
  24. <div className="absolute inset-0 flex items-center m-4" aria-hidden="true">
  25. <div className="w-full border-t border-gray-100" />
  26. </div>
  27. <div className='text-gray-700 text-sm'>
  28. {history.target}
  29. </div>
  30. </div>
  31. )
  32. }
  33. const History = ({
  34. dictionary,
  35. }: IHistoryProps) => {
  36. const { data, error } = useSWR('http://localhost:3000/api/histories', fetchHistories)
  37. const [showHistory, setShowHistory] = useState(false)
  38. const DivideLine = () => {
  39. return <div className="mt-6 relative">
  40. {/* divider line */}
  41. <div className="absolute inset-0 flex items-center" aria-hidden="true">
  42. <div className="w-full border-t border-gray-300" />
  43. </div>
  44. <div className="relative flex justify-center flex-col items-center">
  45. {!showHistory ? <ChevronUpIcon className="h-3 w-3 text-gray-500" aria-hidden="true" /> : <div className='h-3 w-3' />}
  46. <span className="px-2 bg-white text-sm font-medium text-gray-600 cursor-pointer">{dictionary.app.textGeneration.history}</span>
  47. {!showHistory ? <div className='h-3 w-3' /> : <ChevronDownIcon className="h-3 w-3 text-gray-500" aria-hidden="true" />}
  48. </div>
  49. </div>
  50. }
  51. if (error)
  52. return <div>failed to load</div>
  53. if (!data)
  54. return <Loading />
  55. return showHistory
  56. ? <div className='w-1/2 block fixed bottom-0 right-0 px-10 py-4' onClick={
  57. () => setShowHistory(v => !v)
  58. }>
  59. <DivideLine />
  60. <div
  61. className='mt-4 grid grid-cols-3 space-x-4 h-[400px] overflow-auto'
  62. >
  63. {data.histories.map((item: HistoryItem) =>
  64. <HistoryCard key={item.id} history={item} />)}
  65. </div>
  66. </div>
  67. : <div className='w-1/2 block fixed bottom-0 right-0 px-10 py-4' onClick={
  68. () => setShowHistory(true)
  69. }>
  70. <DivideLine />
  71. </div>
  72. }
  73. export default History