update 25/03

This commit is contained in:
2025-03-25 14:18:53 +07:00
parent 27057c8588
commit cc8b18bbc9
2 changed files with 273 additions and 168 deletions

View File

@@ -1,5 +1,5 @@
"use client"; "use client";
import { useState, useEffect } from "react"; import { Suspense, useState, useEffect } from "react";
import { useParams } from "next/navigation"; import { useParams } from "next/navigation";
import { JobDetailDataType } from "@/types/job"; import { JobDetailDataType } from "@/types/job";
import { fetchJobDetail } from "@/api/apiService"; import { fetchJobDetail } from "@/api/apiService";
@@ -8,6 +8,7 @@ const JobDetails = () => {
const [JobDetail, setJobDetail] = useState<JobDetailDataType | null>(null); const [JobDetail, setJobDetail] = useState<JobDetailDataType | null>(null);
const [activeTab, setActiveTab] = useState("#info"); const [activeTab, setActiveTab] = useState("#info");
const { slug } = useParams(); const { slug } = useParams();
const [loadingUi, setLoadingUI] = useState(true);
const showTab = (tab: string) => { const showTab = (tab: string) => {
setActiveTab(tab); setActiveTab(tab);
@@ -18,6 +19,7 @@ const JobDetails = () => {
const getJobDetail = async () => { const getJobDetail = async () => {
const data = await fetchJobDetail(slug); const data = await fetchJobDetail(slug);
setJobDetail(data[0]); setJobDetail(data[0]);
setLoadingUI(false);
}; };
getJobDetail(); getJobDetail();
} }
@@ -25,164 +27,212 @@ const JobDetails = () => {
return ( return (
<div className="page-job detail"> <div className="page-job detail">
{JobDetail ? ( <Suspense>
<div className="container-job"> {loadingUi ? (
<h2 className="title">{JobDetail.title}</h2> <div className="container-job">
<div className="content-job flex"> <h2 className="title animate-fade-in text-xl font-medium bg-gray-200 rounded-[12px]"></h2>
<div className="left-job"> <div className="content-job flex">
<div className="item"> <div className="left-job">
<p>Đa điểm</p> <div className="item">
<b>{JobDetail.location}</b> <p className="bg-gray-200 h-[20px] block w-full"></p>
<b className="bg-gray-200 h-[20px] block w-full"></b>
</div>
<div className="item">
<p className="bg-gray-200 h-[20px] block w-full"></p>
<b className="bg-gray-200 h-[20px] block w-full"></b>
</div>
<div className="item">
<p className="bg-gray-200 h-[20px] block w-full"></p>
<b className="bg-gray-200 h-[20px] block w-full"></b>
</div>
</div> </div>
<div className="item"> <div className="right-job">
<p>Hình thức làm việc</p> <div className="list-tab flex items-center">
<b>Toàn thời gian cố đnh</b> <div className="item-tab bg-gray-200 w-[170px] h-[45px] mr-[12px] rounded-[5px]"></div>
</div> <div className="item-tab bg-gray-200 w-[170px] h-[45px] mr-[12px] rounded-[5px]"></div>
<div className="item"> </div>
<p>Số lượng tuyển</p> <div>
<b>{JobDetail.applicant_count}</b> <div className="bg-gray-200 w-full h-[30px] rounded-[5px] ml-[20px] mb-[20px]"></div>
<ul>
<li className="bg-gray-200 w-full h-[20px] rounded-[5px] mb-[10px] ml-[10px]"></li>
<li className="bg-gray-200 w-full h-[20px] rounded-[5px] mb-[10px] ml-[10px]"></li>
<li className="bg-gray-200 w-full h-[20px] rounded-[5px] mb-[10px] ml-[10px]"></li>
<li className="bg-gray-200 w-full h-[20px] rounded-[5px] mb-[10px] ml-[10px]"></li>
<li className="bg-gray-200 w-full h-[20px] rounded-[5px] mb-[10px] ml-[10px]"></li>
</ul>
</div>
</div> </div>
</div> </div>
<div className="right-job"> </div>
<div className="list-tab flex items-center"> ) : (
<div <div>
onClick={() => showTab("#info")} {JobDetail ? (
data-id="#info" <div className="container-job">
className={`item-tab ${ <h2 className="title">{JobDetail.title}</h2>
activeTab === "#info" ? "active" : "" <div className="content-job flex">
}`} <div className="left-job">
> <div className="item">
Chi tiết <p>Đa điểm</p>
</div> <b>{JobDetail.location}</b>
<div </div>
onClick={() => showTab("#formjob")} <div className="item">
data-id="#formjob" <p>Hình thức làm việc</p>
className={`item-tab ${ <b>Toàn thời gian cố đnh</b>
activeTab === "#formjob" ? "active" : "" </div>
}`} <div className="item">
> <p>Số lượng tuyển</p>
Nộp hồ <b>{JobDetail.applicant_count}</b>
</div>
</div>
<div
className={`content-tab ${
activeTab === "#info" ? "active" : ""
}`}
id="info"
>
<div
dangerouslySetInnerHTML={{ __html: JobDetail.description }}
/>
<a
href="javascript:void(0)"
onClick={() => showTab("#formjob")}
className="btn apply-job"
>
ng tuyển ngay
</a>
</div>
<div
className={`content-tab ${
activeTab === "#formjob" ? "active" : ""
}`}
id="formjob"
>
<input type="hidden" id="js-job_id" value="13" />
<div className="item-upload d-flex flex-wrap align-items">
<div className="upload-left">
<div className="d-flex align-items">
<i className="fa-solid fa-cloud-arrow-up"></i>
<p className="name-up">Tải lên yếu lịch</p>
</div> </div>
<p className="gray">
Tải yếu lịch của bạn lên đây đ tự đng điền các
thông tin chính.
</p>
</div> </div>
<div className="upload-right"> <div className="right-job">
<input id="js-file-upload-id" type="hidden" value="" /> <div className="list-tab flex items-center">
<div id="js-container-selector"> <div
<a onClick={() => showTab("#info")}
id="js-select-file" data-id="#info"
href="#" className={`item-tab ${
className="btn-upload d-block dz-clickable" activeTab === "#info" ? "active" : ""
}`}
> >
Upload file Chi tiết
</div>
<div
onClick={() => showTab("#formjob")}
data-id="#formjob"
className={`item-tab ${
activeTab === "#formjob" ? "active" : ""
}`}
>
Nộp hồ
</div>
</div>
<div
className={`content-tab ${
activeTab === "#info" ? "active" : ""
}`}
id="info"
>
<div
dangerouslySetInnerHTML={{
__html: JobDetail.description,
}}
/>
<a
href="javascript:void(0)"
onClick={() => showTab("#formjob")}
className="btn apply-job"
>
ng tuyển ngay
</a>
</div>
<div
className={`content-tab ${
activeTab === "#formjob" ? "active" : ""
}`}
id="formjob"
>
<input type="hidden" id="js-job_id" value="13" />
<div className="item-upload d-flex flex-wrap align-items">
<div className="upload-left">
<div className="d-flex align-items">
<i className="fa-solid fa-cloud-arrow-up"></i>
<p className="name-up">Tải lên yếu lịch</p>
</div>
<p className="gray">
Tải yếu lịch của bạn lên đây đ tự đng điền
các thông tin chính.
</p>
</div>
<div className="upload-right">
<input
id="js-file-upload-id"
type="hidden"
value=""
/>
<div id="js-container-selector">
<a
id="js-select-file"
href="#"
className="btn-upload d-block dz-clickable"
>
Upload file
</a>
</div>
</div>
<div className="pd-preview-file-upload">
<div id="js-file-uploaded-list"></div>
<div id="js-preview-file-upload"></div>
</div>
</div>
<div className="item-form">
<label>
Tên <span>*</span>
</label>
<input
type="text"
className="input-item"
name="name"
id="js-user_name"
placeholder="Nhập họ và tên"
/>
<div className="note-error"></div>
</div>
<div className="item-form">
<label>
Email <span>*</span>
</label>
<input
type="text"
className="input-item"
name="email"
id="js-user_email"
placeholder="Nhập địa chỉ email"
/>
<div className="note-error"></div>
</div>
<div className="item-form">
<label>
Số điện thoại <span>*</span>
</label>
<input
type="text"
className="input-item"
name="phone"
id="js-user_mobile"
placeholder="Nhập số điện thoại"
/>
<div className="note-error"></div>
</div>
<div className="item-form">
<label>Thông tin bổ sung</label>
<span className="ghichu">
Vui lòng chia sẻ bất kỳ điều khác bạn muốn chúng
tôi biết, chẳng hạn như đng lực của bạn khi ng tuyển
hoặc các bối cảnh bổ sung liên quan đến hồ của bạn.
</span>
<textarea
className="input-item"
name="messenger"
id="js-user_note"
placeholder="Nhập nội dung bổ sung"
></textarea>
</div>
<a href="javascript:void(0)" className="btn btn-submit">
Nộp đơn <i className="fa-regular fa-paper-plane"></i>
</a> </a>
</div> </div>
</div> </div>
<div className="pd-preview-file-upload">
<div id="js-file-uploaded-list"></div>
<div id="js-preview-file-upload"></div>
</div>
</div> </div>
<div className="item-form">
<label>
Tên <span>*</span>
</label>
<input
type="text"
className="input-item"
name="name"
id="js-user_name"
placeholder="Nhập họ và tên"
/>
<div className="note-error"></div>
</div>
<div className="item-form">
<label>
Email <span>*</span>
</label>
<input
type="text"
className="input-item"
name="email"
id="js-user_email"
placeholder="Nhập địa chỉ email"
/>
<div className="note-error"></div>
</div>
<div className="item-form">
<label>
Số điện thoại <span>*</span>
</label>
<input
type="text"
className="input-item"
name="phone"
id="js-user_mobile"
placeholder="Nhập số điện thoại"
/>
<div className="note-error"></div>
</div>
<div className="item-form">
<label>Thông tin bổ sung</label>
<span className="ghichu">
Vui lòng chia sẻ bất kỳ điều khác bạn muốn chúng tôi
biết, chẳng hạn như đng lực của bạn khi ng tuyển hoặc các
bối cảnh bổ sung liên quan đến hồ của bạn.
</span>
<textarea
className="input-item"
name="messenger"
id="js-user_note"
placeholder="Nhập nội dung bổ sung"
></textarea>
</div>
<a href="javascript:void(0)" className="btn btn-submit">
Nộp đơn <i className="fa-regular fa-paper-plane"></i>
</a>
</div> </div>
</div> ) : (
<div className="container-job">
<div className="text-center text-2xl py-[50px] font-bold italic">
Không công việc nào.
</div>
</div>
)}
</div> </div>
</div> )}
) : ( </Suspense>
<div className="container-job">
<div className="text-center text-2xl py-[50px] font-bold italic">
Không công việc nào.
</div>
</div>
)}
</div> </div>
); );
}; };

View File

@@ -1,16 +1,18 @@
"use client"; "use client";
import Link from "next/link"; import Link from "next/link";
import { useState, useEffect } from "react"; import { Suspense, useState, useEffect } from "react";
import { ListJobDataType } from "@/types/job"; import { ListJobDataType } from "@/types/job";
import { fetchListJobs } from "@/api/apiService"; import { fetchListJobs } from "@/api/apiService";
const HomeJob = () => { const HomeJob = () => {
const [ListJob, setListJob] = useState<ListJobDataType | null>(null); const [ListJob, setListJob] = useState<ListJobDataType | null>(null);
const [loadingUi, setLoadingUI] = useState(true);
useEffect(() => { useEffect(() => {
const getListJob = async () => { const getListJob = async () => {
const data = await fetchListJobs(); const data = await fetchListJobs();
setListJob(data.list); setListJob(data.list);
setLoadingUI(false);
}; };
getListJob(); getListJob();
@@ -20,30 +22,83 @@ const HomeJob = () => {
<div className="page-job list"> <div className="page-job list">
<div className="container-job"> <div className="container-job">
<h2 className="title">Tuyển dụng</h2> <h2 className="title">Tuyển dụng</h2>
{ListJob && Array.isArray(ListJob) && ListJob.length > 0 ? ( <Suspense>
<div className="list-job"> {loadingUi ? (
{ListJob.map((item) => ( <div className="list-job">
<div className="item-job" key={item.id}> <div className="item-job">
<div className="job-left"> <div className="job-left flex items-center">
<Link href={`${item.url}`} className="name line-clamp-1"> <div className="name line-clamp-1 bg-gray-200 h-[21px] w-[300px] mr-[15px]"></div>
{item.title} <div className="time bg-gray-200 h-[20px] w-[120px] block"></div>
</Link>
<div className="time">{item.end_date}</div>
</div> </div>
<div className="job-right flex items-center"> <div className="job-right flex items-center">
<div className="localhost">{item.location}</div> <div className="localhost bg-gray-200 h-[21px] w-[60px] mr-[20px] block"></div>
<Link href={`${item.url}`} className="more"> <div className="more bg-gray-200 h-[21px] block w-[120px]"></div>
ng tuyển ngay <i className="fa-solid fa-angle-right"></i>
</Link>
</div> </div>
</div> </div>
))} <div className="item-job">
</div> <div className="job-left flex items-center">
) : ( <div className="name line-clamp-1 bg-gray-200 h-[21px] w-[300px] mr-[15px]"></div>
<div className="text-center text-2xl py-[50px] font-bold italic"> <div className="time bg-gray-200 h-[20px] w-[120px] block"></div>
Không công việc nào. </div>
</div> <div className="job-right flex items-center">
)} <div className="localhost bg-gray-200 h-[21px] w-[60px] mr-[20px] block"></div>
<div className="more bg-gray-200 h-[21px] block w-[120px]"></div>
</div>
</div>
<div className="item-job">
<div className="job-left flex items-center">
<div className="name line-clamp-1 bg-gray-200 h-[21px] w-[300px] mr-[15px]"></div>
<div className="time bg-gray-200 h-[20px] w-[120px] block"></div>
</div>
<div className="job-right flex items-center">
<div className="localhost bg-gray-200 h-[21px] w-[60px] mr-[20px] block"></div>
<div className="more bg-gray-200 h-[21px] block w-[120px]"></div>
</div>
</div>
<div className="item-job">
<div className="job-left flex items-center">
<div className="name line-clamp-1 bg-gray-200 h-[21px] w-[300px] mr-[15px]"></div>
<div className="time bg-gray-200 h-[20px] w-[120px] block"></div>
</div>
<div className="job-right flex items-center">
<div className="localhost bg-gray-200 h-[21px] w-[60px] mr-[20px] block"></div>
<div className="more bg-gray-200 h-[21px] block w-[120px]"></div>
</div>
</div>
</div>
) : (
<div>
{ListJob && Array.isArray(ListJob) && ListJob.length > 0 ? (
<div className="list-job">
{ListJob.map((item) => (
<div className="item-job" key={item.id}>
<div className="job-left">
<Link
href={`${item.url}`}
className="name line-clamp-1"
>
{item.title}
</Link>
<div className="time">{item.end_date}</div>
</div>
<div className="job-right flex items-center">
<div className="localhost">{item.location}</div>
<Link href={`${item.url}`} className="more">
ng tuyển ngay{" "}
<i className="fa-solid fa-angle-right"></i>
</Link>
</div>
</div>
))}
</div>
) : (
<div className="text-center text-2xl py-[50px] font-bold italic">
Không công việc nào.
</div>
)}
</div>
)}
</Suspense>
</div> </div>
</div> </div>
); );