refactor: improve some styles, develop ResultBox component & use it at all panels
All checks were successful
Build and Deploy Next.js + Nginx Docker Image / build-and-deploy (push) Successful in 2m51s
Build and Deploy Next.js + Nginx Docker Image / deploy (push) Successful in 7s

This commit is contained in:
Hossein Salari 2026-02-25 14:18:01 +03:30
parent 68b244afd4
commit 9faecb783a
6 changed files with 130 additions and 55 deletions

View File

@ -0,0 +1,34 @@
import { Box } from "@chakra-ui/react";
import { keyframes } from "@emotion/react";
const pulse = keyframes`
0% {
transform: scale(0.7);
opacity: 0.4;
box-shadow: 0 0 0 0 rgba(147, 51, 234, 0.4);
}
50% {
transform: scale(1);
opacity: 1;
box-shadow: 0 0 0 8px rgba(147, 51, 234, 0);
}
100% {
transform: scale(0.7);
opacity: 0.4;
box-shadow: 0 0 0 0 rgba(147, 51, 234, 0);
}
`;
const ChatTypingLoader = ({ size = "10px", color = "purple.400" }) => {
return (
<Box
w={size}
h={size}
borderRadius="full"
bg={color}
animation={`${pulse} 1.1s ease-in-out infinite`}
/>
);
};
export default ChatTypingLoader;

View File

@ -7,13 +7,9 @@ import {
HStack, HStack,
Icon, Icon,
Input, Input,
Select,
Table, Table,
TableCaption,
TableContainer, TableContainer,
Tbody, Tbody,
Td,
Text,
Textarea, Textarea,
Th, Th,
Thead, Thead,
@ -23,8 +19,8 @@ import {
import { TbMathMax, TbPrompt } from "react-icons/tb"; import { TbMathMax, TbPrompt } from "react-icons/tb";
import { FaDraft2Digital } from "react-icons/fa"; import { FaDraft2Digital } from "react-icons/fa";
import { FaPlay } from "react-icons/fa"; import { FaPlay } from "react-icons/fa";
import { MdOutlineQuestionAnswer } from "react-icons/md";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import ResultBox from "../ui/ResultBox";
export default function LlmPanel() { export default function LlmPanel() {
const { register, handleSubmit } = useForm(); const { register, handleSubmit } = useForm();
@ -94,28 +90,19 @@ export default function LlmPanel() {
<Button p={"20px"} colorScheme="pink" leftIcon={<FaPlay />} type="submit"> <Button p={"20px"} colorScheme="pink" leftIcon={<FaPlay />} type="submit">
اجرا اجرا
</Button> </Button>
<Divider my={"20px"} /> <Divider my={"20px"} borderColor={"gray.300"} />
<TableContainer w={"100%"} mt={"10px"}> <TableContainer w={"100%"} mt={"10px"}>
<Table> <Table>
<Thead> <Thead>
<Tr> <Tr>
<Th fontSize={"20px"}>ردیف</Th> <Th fontSize={"md"}>ردیف</Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody></Tbody> <Tbody></Tbody>
</Table> </Table>
</TableContainer> </TableContainer>
<Divider my={"20px"} /> <Divider my={"20px"} borderColor={"gray.300"} />
<FormControl <ResultBox type="llm" />
bgColor={"purple.50"}
border={"1px"}
borderColor={"gray.200"}
p={"10px"}
borderRadius={"10px"}
>
<FormLabel fontSize={"20px"}>نتیجه</FormLabel>
<Textarea bgColor={"white"} />
</FormControl>
</VStack> </VStack>
); );
} }

View File

@ -1,6 +1,5 @@
// components/PhoneInput.tsx // components/PhoneInput.tsx
import { import {
Box,
Button, Button,
Divider, Divider,
FormControl, FormControl,
@ -8,13 +7,9 @@ import {
HStack, HStack,
Icon, Icon,
Input, Input,
Select,
Table, Table,
TableCaption,
TableContainer, TableContainer,
Tbody, Tbody,
Td,
Text,
Textarea, Textarea,
Th, Th,
Thead, Thead,
@ -28,6 +23,7 @@ import { TbPrompt } from "react-icons/tb";
import { FaDraft2Digital, FaPlay } from "react-icons/fa"; import { FaDraft2Digital, FaPlay } from "react-icons/fa";
import { useState } from "react"; import { useState } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import ResultBox from "../ui/ResultBox";
export default function TextImagePanel() { export default function TextImagePanel() {
const { register, handleSubmit } = useForm(""); const { register, handleSubmit } = useForm("");
@ -136,28 +132,19 @@ export default function TextImagePanel() {
<Button p={"20px"} colorScheme="pink" leftIcon={<FaPlay />} type="submit"> <Button p={"20px"} colorScheme="pink" leftIcon={<FaPlay />} type="submit">
اجرا اجرا
</Button> </Button>
<Divider my={"20px"} /> <Divider my={"20px"} borderColor={"gray.300"} />
<TableContainer w={"100%"} mt={"10px"}> <TableContainer w={"100%"} mt={"10px"}>
<Table> <Table>
<Thead> <Thead>
<Tr> <Tr>
<Th fontSize={"20px"}>ردیف</Th> <Th fontSize={"md"}>ردیف</Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody></Tbody> <Tbody></Tbody>
</Table> </Table>
</TableContainer> </TableContainer>
<Divider my={"20px"} /> <Divider my={"20px"} borderColor={"gray.300"} />
<FormControl <ResultBox type="image" />
bgColor={"purple.50"}
border={"1px"}
borderColor={"gray.200"}
p={"10px"}
borderRadius={"10px"}
>
<FormLabel fontSize={"20px"}>نتیجه</FormLabel>
<Textarea bgColor={"white"} />
</FormControl>
</VStack> </VStack>
); );
} }

View File

@ -1,6 +1,5 @@
// components/PhoneInput.tsx // components/PhoneInput.tsx
import { import {
Box,
Button, Button,
Divider, Divider,
FormControl, FormControl,
@ -8,13 +7,9 @@ import {
HStack, HStack,
Icon, Icon,
Input, Input,
Select,
Table, Table,
TableCaption,
TableContainer, TableContainer,
Tbody, Tbody,
Td,
Text,
Textarea, Textarea,
Th, Th,
Thead, Thead,
@ -26,6 +21,7 @@ import { TbArrowGuide } from "react-icons/tb";
import { TbPrompt } from "react-icons/tb"; import { TbPrompt } from "react-icons/tb";
import { FaDraft2Digital, FaPlay } from "react-icons/fa"; import { FaDraft2Digital, FaPlay } from "react-icons/fa";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import ResultBox from "../ui/ResultBox";
export default function TextVideoPanel() { export default function TextVideoPanel() {
const { register, handleSubmit } = useForm(); const { register, handleSubmit } = useForm();
@ -115,28 +111,19 @@ export default function TextVideoPanel() {
<Button p={"20px"} colorScheme="pink" leftIcon={<FaPlay />} type="submit"> <Button p={"20px"} colorScheme="pink" leftIcon={<FaPlay />} type="submit">
اجرا اجرا
</Button> </Button>
<Divider my={"20px"} /> <Divider my={"20px"} borderColor={"gray.300"} />
<TableContainer w={"100%"} mt={"10px"}> <TableContainer w={"100%"} mt={"10px"}>
<Table> <Table>
<Thead> <Thead>
<Tr> <Tr>
<Th fontSize={"20px"}>ردیف</Th> <Th fontSize={"md"}>ردیف</Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody></Tbody> <Tbody></Tbody>
</Table> </Table>
</TableContainer> </TableContainer>
<Divider my={"20px"} /> <Divider my={"20px"} borderColor={"gray.300"} />
<FormControl <ResultBox type="video" />
bgColor={"purple.50"}
border={"1px"}
borderColor={"gray.200"}
p={"10px"}
borderRadius={"10px"}
>
<FormLabel fontSize={"20px"}>نتیجه</FormLabel>
<Textarea bgColor={"white"} />
</FormControl>
</VStack> </VStack>
); );
} }

View File

@ -0,0 +1,62 @@
import { Box, HStack, Icon, Text } from "@chakra-ui/react";
import { FaBolt } from "react-icons/fa";
import ChatTypingLoader from "../loading/ChatTypingLoader";
import {
IoDocumentTextOutline,
IoImageOutline,
IoVideocamOutline,
} from "react-icons/io5";
const iconsDic = {
llm: IoDocumentTextOutline,
image: IoImageOutline,
video: IoVideocamOutline,
};
function ResultBox({ type = "llm", loading = false, resultData = "" }) {
return (
<Box
w={"100%"}
minHeight={"200px"}
p={4}
bg="#f5effd"
boxShadow="sm"
marginBottom={"4px"}
border={"1px"}
borderColor={"purple.100"}
borderRadius={"10px"}
>
<Box
width={"100%"}
backgroundColor={"white"}
padding={"5px"}
borderRadius={"5px"}
as={HStack}
justifyContent={"space-between"}
id="question"
>
<HStack alignItems={"center"} justifyContent={"start"}>
<Icon as={iconsDic[type]} fontSize={"20px"} />
<Text fontWeight="bold" fontSize={"18px"}>
نتیجه
</Text>
</HStack>
<FaBolt color="purple" />
</Box>
<Box mt={4} whiteSpace="pre-line">
{loading && (
<HStack
w="100%"
alignItems="center"
justifyContent="flex-start"
mt={2}
>
<ChatTypingLoader size="16px" />
</HStack>
)}
</Box>
</Box>
);
}
export default ResultBox;

View File

@ -52,6 +52,13 @@ export default function Home() {
borderLeft="1px solid" borderLeft="1px solid"
borderColor="gray.200" borderColor="gray.200"
py={8} py={8}
overflowY={"auto"}
maxH={"calc(100vh - 92px)"}
sx={{
"::-webkit-scrollbar": { display: "none" },
"scrollbar-width": "none",
"-ms-overflow-style": "none",
}}
> >
<VStack align="stretch" spacing={6}> <VStack align="stretch" spacing={6}>
{/* Menu */} {/* Menu */}
@ -185,7 +192,18 @@ export default function Home() {
</Box> </Box>
{/* Content */} {/* Content */}
<Box flex="1" p={8} minW={0}> <Box
flex="1"
p={8}
minW={0}
overflowY={"auto"}
maxH={"calc(100vh - 92px)"}
sx={{
"::-webkit-scrollbar": { display: "none" },
"scrollbar-width": "none",
"-ms-overflow-style": "none",
}}
>
<Tabs <Tabs
variant="soft-rounded" variant="soft-rounded"
colorScheme="purple" colorScheme="purple"