Merge pull request #48 from rede5/codex/refactor-home-ui-for-gohorse-jobs
refactor(frontend): improve home page UI hierarchy and mobile responsiveness
This commit is contained in:
commit
21ac2ab2e0
3 changed files with 29 additions and 29 deletions
|
|
@ -53,19 +53,19 @@ export default function Home() {
|
|||
|
||||
<main className="flex-grow">
|
||||
{/* Hero Section */}
|
||||
<section className="relative h-[500px] flex items-center justify-center bg-[#1F2F40]">
|
||||
<section className="relative h-[520px] flex items-center justify-center bg-[#1F2F40]">
|
||||
<div className="absolute inset-0 z-0">
|
||||
<Image
|
||||
src="/10.png"
|
||||
alt="Background"
|
||||
fill
|
||||
className="object-cover opacity-60 contrast-125"
|
||||
className="object-cover opacity-55 contrast-125"
|
||||
priority
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-[#1F2F40] via-[#1F2F40]/90 to-transparent" />
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-[#132131]/95 via-[#1F2F40]/90 to-[#1F2F40]/45" />
|
||||
</div>
|
||||
|
||||
<div className="container mx-auto px-4 relative z-10 text-center sm:text-left">
|
||||
<div className="container mx-auto px-4 sm:px-6 relative z-10 text-center sm:text-left">
|
||||
<div className="max-w-3xl">
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
|
|
@ -92,7 +92,7 @@ export default function Home() {
|
|||
transition={{ duration: 0.5, delay: 0.2 }}
|
||||
>
|
||||
<Link href="/jobs">
|
||||
<Button className="h-12 px-8 bg-orange-500 hover:bg-orange-600 text-white font-bold text-lg rounded-md shadow-lg transition-transform hover:scale-105">
|
||||
<Button className="h-12 px-8 bg-orange-500 hover:bg-orange-600 text-white font-bold text-lg rounded-lg shadow-lg transition-transform hover:scale-105">
|
||||
{t("home.hero.cta")}
|
||||
</Button>
|
||||
</Link>
|
||||
|
|
@ -102,7 +102,7 @@ export default function Home() {
|
|||
</section>
|
||||
|
||||
{/* Search Section */}
|
||||
<section className="px-4 mb-16">
|
||||
<section className="px-4 sm:px-6 mb-16">
|
||||
<div className="container mx-auto">
|
||||
<HomeSearch />
|
||||
</div>
|
||||
|
|
@ -110,7 +110,7 @@ export default function Home() {
|
|||
|
||||
{/* Latest Jobs Section */}
|
||||
<section className="py-12 bg-gray-50">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="container mx-auto px-4 sm:px-6">
|
||||
<div className="flex items-center justify-between mb-8">
|
||||
<h2 className="text-2xl md:text-3xl font-bold text-gray-900">
|
||||
{t("home.featuredJobs.title")}
|
||||
|
|
@ -140,7 +140,7 @@ export default function Home() {
|
|||
<div className="overflow-hidden" ref={emblaRef}>
|
||||
<div className="flex gap-6">
|
||||
{mockJobs.slice(0, 8).map((job, index) => (
|
||||
<div key={`latest-${job.id}-${index}`} className="flex-[0_0_100%] sm:flex-[0_0_50%] lg:flex-[0_0_25%] min-w-0">
|
||||
<div key={`latest-${job.id}-${index}`} className="flex-[0_0_100%] sm:flex-[0_0_50%] lg:flex-[0_0_25%] min-w-0 pb-1">
|
||||
<JobCard job={job} />
|
||||
</div>
|
||||
))}
|
||||
|
|
@ -151,13 +151,13 @@ export default function Home() {
|
|||
|
||||
{/* More Jobs Section */}
|
||||
<section className="py-12 bg-white">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="container mx-auto px-4 sm:px-6">
|
||||
<div className="flex items-center justify-between mb-8">
|
||||
<h2 className="text-2xl md:text-3xl font-bold text-gray-900">
|
||||
{t("home.moreJobs.title")}
|
||||
</h2>
|
||||
<Link href="/jobs">
|
||||
<Button className="bg-orange-500 hover:bg-orange-600 text-white font-bold">
|
||||
<Button className="bg-orange-500 hover:bg-orange-600 text-white font-bold rounded-lg">
|
||||
{t("home.moreJobs.viewAll")}
|
||||
</Button>
|
||||
</Link>
|
||||
|
|
@ -173,7 +173,7 @@ export default function Home() {
|
|||
|
||||
{/* Bottom CTA Section */}
|
||||
<section className="py-16 bg-white">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="container mx-auto px-4 sm:px-6">
|
||||
<div className="bg-[#1F2F40] rounded-[2rem] p-8 md:p-16 relative overflow-hidden text-center md:text-left flex flex-col md:flex-row items-center justify-between min-h-[400px]">
|
||||
<div className="relative z-10 max-w-xl">
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-white mb-4 leading-tight">
|
||||
|
|
@ -183,7 +183,7 @@ export default function Home() {
|
|||
{t("home.cta.subtitle")}
|
||||
</p>
|
||||
<Link href="/register/user">
|
||||
<Button className="h-12 px-8 bg-white text-gray-900 hover:bg-gray-100 font-bold text-lg rounded-md">
|
||||
<Button className="h-12 px-8 bg-white text-gray-900 hover:bg-gray-100 font-bold text-lg rounded-lg">
|
||||
{t("home.cta.button")}
|
||||
</Button>
|
||||
</Link>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { Search, MapPin, DollarSign, Briefcase } from "lucide-react"
|
||||
import { Search } from "lucide-react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
||||
|
|
@ -29,7 +29,7 @@ export function HomeSearch() {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-lg shadow-lg p-6 max-w-5xl mx-auto -mt-24 relative z-20 border border-gray-100">
|
||||
<div className="bg-white rounded-2xl shadow-lg p-4 sm:p-6 max-w-6xl mx-auto -mt-24 relative z-20 border border-gray-200 w-full">
|
||||
<div className="mb-4">
|
||||
<div className="relative">
|
||||
<Search className="absolute left-3 top-3 h-5 w-5 text-gray-400" />
|
||||
|
|
@ -42,7 +42,7 @@ export function HomeSearch() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-5 gap-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-5 gap-4 items-end">
|
||||
{/* Contract Type */}
|
||||
<div className="space-y-2">
|
||||
<label className="text-xs font-semibold text-gray-700 uppercase tracking-wide">{t("home.search.contractType")}</label>
|
||||
|
|
@ -102,10 +102,10 @@ export function HomeSearch() {
|
|||
</div>
|
||||
|
||||
{/* Search Button */}
|
||||
<div className="flex items-end">
|
||||
<div className="flex items-end h-full">
|
||||
<Button
|
||||
onClick={handleSearch}
|
||||
className="w-full h-12 bg-orange-500 hover:bg-orange-600 text-white font-bold text-lg shadow-md transition-all active:scale-95"
|
||||
className="w-full h-12 bg-orange-500 hover:bg-orange-600 text-white font-bold text-lg shadow-md transition-all active:scale-95 rounded-lg"
|
||||
>
|
||||
<Search className="w-5 h-5 mr-2" />
|
||||
{t("home.search.filter")}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|||
import {
|
||||
MapPin,
|
||||
Briefcase,
|
||||
DollarSign,
|
||||
Clock,
|
||||
Building2,
|
||||
Heart,
|
||||
|
|
@ -95,9 +94,10 @@ export function JobCard({ job, isApplied, applicationStatus }: JobCardProps) {
|
|||
<motion.div
|
||||
whileHover={{ y: -2 }}
|
||||
transition={{ type: "spring", stiffness: 300, damping: 20 }}
|
||||
className="h-full"
|
||||
>
|
||||
<Card className={`relative hover:shadow-lg transition-all duration-300 border-l-4 h-full flex flex-col ${job.isFeatured
|
||||
? "border-l-amber-500 border-amber-200 shadow-md bg-amber-50/10"
|
||||
<Card className={`relative h-full flex flex-col border-l-4 rounded-xl bg-white shadow-sm hover:shadow-md transition-all duration-300 ${job.isFeatured
|
||||
? "border-l-amber-500 border-amber-200 bg-amber-50/10"
|
||||
: "border-l-primary/20 hover:border-l-primary"
|
||||
}`}>
|
||||
<CardHeader className="pb-4">
|
||||
|
|
@ -149,7 +149,7 @@ export function JobCard({ job, isApplied, applicationStatus }: JobCardProps) {
|
|||
</div>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className="space-y-4 flex-1">
|
||||
<CardContent className="space-y-4 flex-1 flex flex-col">
|
||||
{/* Job Meta Information */}
|
||||
{/* Job Meta Information */}
|
||||
<div className="flex flex-col gap-2 text-sm">
|
||||
|
|
@ -163,7 +163,7 @@ export function JobCard({ job, isApplied, applicationStatus }: JobCardProps) {
|
|||
<Briefcase className="h-4 w-4 shrink-0 text-muted-foreground" />
|
||||
<Badge
|
||||
variant={getTypeBadgeVariant(job.type)}
|
||||
className="text-xs"
|
||||
className="text-xs font-semibold text-white bg-orange-500 border-transparent"
|
||||
>
|
||||
{getTypeLabel(job.type)}
|
||||
</Badge>
|
||||
|
|
@ -178,8 +178,8 @@ export function JobCard({ job, isApplied, applicationStatus }: JobCardProps) {
|
|||
</div>
|
||||
|
||||
{/* Job Description Preview */}
|
||||
<div className="text-sm text-muted-foreground">
|
||||
<p className="line-clamp-2">{job.description}</p>
|
||||
<div className="text-sm text-muted-foreground leading-relaxed">
|
||||
<p className="line-clamp-3">{job.description}</p>
|
||||
</div>
|
||||
|
||||
{/* Skills/Requirements Preview */}
|
||||
|
|
@ -202,21 +202,21 @@ export function JobCard({ job, isApplied, applicationStatus }: JobCardProps) {
|
|||
)}
|
||||
|
||||
{/* Time Posted */}
|
||||
<div className="flex items-center gap-2 text-xs text-muted-foreground">
|
||||
<div className="flex items-center gap-2 text-xs text-muted-foreground mt-auto">
|
||||
<Clock className="h-3 w-3" />
|
||||
<span>{formatTimeAgo(job.postedAt)}</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
<CardFooter className="pt-4 border-t">
|
||||
<CardFooter className="pt-4 border-t mt-auto">
|
||||
<div className="flex gap-2 w-full">
|
||||
<Link href={`/jobs/${job.id}`} className="flex-1">
|
||||
<Button variant="outline" className="w-full cursor-pointer">
|
||||
<Button variant="outline" className="w-full cursor-pointer rounded-lg">
|
||||
{t('jobs.card.viewDetails')}
|
||||
</Button>
|
||||
</Link>
|
||||
{isApplied ? (
|
||||
<Button className="flex-1 w-full cursor-default bg-emerald-600 hover:bg-emerald-700 text-white" variant="secondary">
|
||||
<Button className="flex-1 w-full cursor-default bg-emerald-600 hover:bg-emerald-700 text-white rounded-lg" variant="secondary">
|
||||
{applicationStatus === 'pending' ? t('jobs.card.applied') :
|
||||
applicationStatus === 'reviewing' ? t('jobs.card.reviewing') :
|
||||
applicationStatus === 'interview' ? t('jobs.card.interview') :
|
||||
|
|
@ -224,7 +224,7 @@ export function JobCard({ job, isApplied, applicationStatus }: JobCardProps) {
|
|||
</Button>
|
||||
) : (
|
||||
<Link href={`/jobs/${job.id}/apply`} className="flex-1">
|
||||
<Button className="w-full cursor-pointer">{t('jobs.card.apply')}</Button>
|
||||
<Button className="w-full cursor-pointer rounded-lg">{t('jobs.card.apply')}</Button>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue