diff --git a/app/frontend/src/components/pages/VacanciesPage.tsx b/app/frontend/src/components/pages/VacanciesPage.tsx new file mode 100644 index 00000000..98f691a0 --- /dev/null +++ b/app/frontend/src/components/pages/VacanciesPage.tsx @@ -0,0 +1,83 @@ +import { router } from '@inertiajs/react'; +import { Box, Button, CloseButton, Container, Group, Pagination, Text, TextInput, Title } from '@mantine/core'; +import { useForm } from '@mantine/form'; +import { Search } from 'lucide-react'; +import type { VacancyCardProps } from '../../types'; +import { VacancyCard } from '../shared/VacancyCard'; + +type PaginationMeta = { + total_pages: number; + current_page: number; +}; + +type VacancyPageProps = { + vacancies: VacancyCardProps[]; + pagination: PaginationMeta; +}; + +function VacanciesPage({ vacancies, pagination }: VacancyPageProps) { + const form = useForm({ + mode: "uncontrolled", + initialValues: { + search: "", + termsOfService: false, + }, + onValuesChange: (value) => { + if (!value.search) { + handleSearch() + } + } + }); + + const handlePageChange = (pageNumber: number) => { + router.get('', { search: form.getValues().search, page: pageNumber }, { preserveState: true, replace: true }); + } + + function handleSearch() { + router.get('', { search: form.getValues().search, page: 1 }, { + preserveState: true, + replace: true, + }); + } + + if (!vacancies) return "Loading..." + + return ( + + Поиск вакансий + + Найдите работу мечты среди тысяч IT-вакансий + + +
+ + + } + key={form.key('search')} + /> + + + +
+ + {vacancies.map((vacancy) => ( + + ))} + + + +
+ ); +} + +export default VacanciesPage; \ No newline at end of file diff --git a/app/frontend/src/components/shared/VacancyCard/ui/VacancyCard.tsx b/app/frontend/src/components/shared/VacancyCard/ui/VacancyCard.tsx index 5251db9d..69041645 100644 --- a/app/frontend/src/components/shared/VacancyCard/ui/VacancyCard.tsx +++ b/app/frontend/src/components/shared/VacancyCard/ui/VacancyCard.tsx @@ -1,9 +1,8 @@ -import React from "react"; -import type { VacancyCardProps } from "../../../../types"; -import { Card, Group, Text, Badge, Button, Stack, Box } from '@mantine/core'; -import { Building2, MapPin, ChevronDown, ChevronUp, Send } from "lucide-react"; -import { useState } from "react"; import { router } from "@inertiajs/core"; +import { Badge, Box, Button, Card, Group, Stack, Text } from '@mantine/core'; +import { Building2, ChevronDown, ChevronUp, MapPin, Send } from "lucide-react"; +import React, { useState } from "react"; +import type { VacancyCardProps } from "../../../../types"; interface VacancyCardPropsWrapper { props: VacancyCardProps; @@ -15,30 +14,33 @@ export const VacancyCard: React.FC = ({ props }) => { const [skillsExpanded, setSkillsExpanded] = useState(false); - const skillsCutDesktop = skills.slice(0,12); - const remainingSkillsCount = skills.length - 3; - const hasMoreSkills = skills.length > 3; + const skills_array: string[] = skills ? skills.split(',') : [] + + const skillsCutDesktop = skills_array ? skills_array.slice(0, 12) : []; + + const remainingSkillsCount = skills_array ? skills_array.length - 3 : 0; + const hasMoreSkills = skills_array ? skills_array.length > 3 : false; - const displayedSkills = skillsExpanded ? skills : skills.slice(0, 3); + const displayedSkills = skillsExpanded ? (skills_array || []) : (skills_array ? skills_array.slice(0, 3) : []); const handleCardLink = (e: React.MouseEvent) => { e.preventDefault(); - router.get(`/vacancies/${id}`) + router.get(`/vacancies/${id}`); }; const handleButtonLink = (e: React.MouseEvent) => { e.stopPropagation(); - window.open(url, '_blank') - } + window.open(url, '_blank'); + }; return ( - @@ -52,17 +54,17 @@ export const VacancyCard: React.FC = ({ props }) => { {/* Информация о компании */} - {company ? + {company ? - {company.name} + {company} : Название компании не указано } - {city ? + {city ? - {city.name} + {city} : Город не указан } @@ -71,10 +73,10 @@ export const VacancyCard: React.FC = ({ props }) => { {/* Навыки */} - {skills && skills.length > 0 ? ( + {skills_array && skills_array.length > 0 ? ( skillsCutDesktop.map((skill) => ( - = ({ props }) => { {/* Правая часть */} - + {salary ? {salary} : Зарплата не указана } -