feat: improve mobile responsiveness of title details page
- Add responsive breakpoints for backdrop height and container padding - Make title text scale appropriately across device sizes - Stack action buttons vertically on mobile - Adjust spacing, gaps, and font sizes for better mobile UX - Make buttons full-width on mobile, auto-width on larger screens
This commit is contained in:
@@ -33,7 +33,7 @@ export default function TitleDetails({ data }: TitleDetailsProps) {
|
||||
return (
|
||||
<div className="relative min-h-[calc(100vh-4rem)]">
|
||||
{/* Backdrop with gradient overlay */}
|
||||
<div className="absolute inset-0 h-[70vh] lg:h-[80vh]">
|
||||
<div className="absolute inset-0 h-[50vh] sm:h-[60vh] lg:h-[80vh]">
|
||||
{data.backdrop && (
|
||||
<img
|
||||
src={data.backdrop}
|
||||
@@ -48,11 +48,11 @@ export default function TitleDetails({ data }: TitleDetailsProps) {
|
||||
{/* Content */}
|
||||
<div className="relative z-10">
|
||||
{/* Main Content */}
|
||||
<div className="container mx-auto px-6 py-12">
|
||||
<div className="grid items-start gap-12 lg:grid-cols-3">
|
||||
<div className="container mx-auto px-4 py-6 sm:px-6 sm:py-12">
|
||||
<div className="grid grid-cols-1 items-start gap-6 sm:gap-8 lg:grid-cols-3 lg:gap-12">
|
||||
{/* Poster */}
|
||||
<div className="lg:col-span-1">
|
||||
<Card className="overflow-hidden border-border/50 bg-card/50 py-0 backdrop-blur-sm">
|
||||
<div className="mx-auto w-full max-w-[200px] sm:max-w-xs md:max-w-sm lg:col-span-1 lg:max-w-none">
|
||||
<Card className="overflow-hidden border-border/50 bg-card/50 p-0 backdrop-blur-sm">
|
||||
<img
|
||||
src={data.poster ?? "/movie-placeholder.svg"}
|
||||
alt={`${data.title} poster`}
|
||||
@@ -62,10 +62,10 @@ export default function TitleDetails({ data }: TitleDetailsProps) {
|
||||
</div>
|
||||
|
||||
{/* Movie Info */}
|
||||
<div className="space-y-8 lg:col-span-2">
|
||||
<div className="min-w-0 space-y-4 sm:space-y-6 lg:col-span-2">
|
||||
{/* Title and Basic Info */}
|
||||
<div className="space-y-4">
|
||||
<h1 className="text-balance font-bold text-4xl leading-tight md:text-6xl">
|
||||
<div className="space-y-2 sm:space-y-3">
|
||||
<h1 className="text-balance break-words font-bold text-2xl leading-tight sm:text-3xl md:text-4xl lg:text-5xl xl:text-6xl">
|
||||
{data.title}
|
||||
</h1>
|
||||
|
||||
@@ -75,7 +75,7 @@ export default function TitleDetails({ data }: TitleDetailsProps) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-wrap items-center gap-3 text-muted-foreground text-sm">
|
||||
<div className="flex flex-wrap items-center gap-2 text-muted-foreground text-xs sm:gap-3 sm:text-sm">
|
||||
{data.year && (
|
||||
<span className="flex items-center gap-1">
|
||||
<Calendar className="h-4 w-4" />
|
||||
@@ -115,12 +115,12 @@ export default function TitleDetails({ data }: TitleDetailsProps) {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<div className="flex flex-wrap gap-1.5 sm:gap-2">
|
||||
{data.genres.map((genre) => (
|
||||
<Badge
|
||||
key={genre.id}
|
||||
variant="secondary"
|
||||
className="bg-secondary/50 text-secondary-foreground"
|
||||
className="bg-secondary/50 text-secondary-foreground text-xs sm:text-sm"
|
||||
>
|
||||
{genre.name}
|
||||
</Badge>
|
||||
@@ -129,28 +129,36 @@ export default function TitleDetails({ data }: TitleDetailsProps) {
|
||||
</div>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<div className="flex flex-col gap-2 sm:flex-row sm:flex-wrap sm:gap-3">
|
||||
<Button
|
||||
size="lg"
|
||||
className="bg-primary text-primary-foreground hover:bg-primary/90"
|
||||
className="w-full bg-primary text-primary-foreground hover:bg-primary/90 sm:w-auto"
|
||||
>
|
||||
<Play className="mr-2 h-5 w-5" />
|
||||
Watch Trailer
|
||||
</Button>
|
||||
<Button variant="outline" size="lg">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="lg"
|
||||
className="w-full sm:w-auto"
|
||||
>
|
||||
<Bookmark className="mr-2 h-5 w-5" />
|
||||
Watchlist
|
||||
</Button>
|
||||
<Button variant="outline" size="lg">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="lg"
|
||||
className="w-full sm:w-auto"
|
||||
>
|
||||
<Share2 className="mr-2 h-5 w-5" />
|
||||
Share
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Synopsis */}
|
||||
<div className="space-y-3">
|
||||
<h2 className="font-semibold text-xl">Synopsis</h2>
|
||||
<p className="text-pretty text-muted-foreground leading-relaxed">
|
||||
<div className="space-y-2 sm:space-y-3">
|
||||
<h2 className="font-semibold text-lg sm:text-xl">Synopsis</h2>
|
||||
<p className="text-pretty text-muted-foreground text-sm leading-relaxed sm:text-base">
|
||||
{data.synopsis ?? "No synopsis available."}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -51,7 +51,7 @@ function RouteComponent() {
|
||||
if (error) {
|
||||
const errorInfo = parseTRPCError(error);
|
||||
return (
|
||||
<div className="container mx-auto px-6 py-12">
|
||||
<div className="container mx-auto px-4 py-6 sm:px-6 sm:py-12">
|
||||
<Alert variant="destructive">
|
||||
<AlertCircle className="h-4 w-4" />
|
||||
<AlertTitle>{errorInfo.title}</AlertTitle>
|
||||
@@ -59,7 +59,7 @@ function RouteComponent() {
|
||||
</Alert>
|
||||
<div className="mt-6">
|
||||
<Link to="/home">
|
||||
<Button variant="outline">
|
||||
<Button variant="outline" className="w-full sm:w-auto">
|
||||
<ArrowLeft className="mr-2 h-4 w-4" />
|
||||
Back to Home
|
||||
</Button>
|
||||
@@ -72,7 +72,7 @@ function RouteComponent() {
|
||||
// Success state
|
||||
if (!data) {
|
||||
return (
|
||||
<div className="container mx-auto px-6 py-12">
|
||||
<div className="container mx-auto px-4 py-6 sm:px-6 sm:py-12">
|
||||
<Alert>
|
||||
<AlertCircle className="h-4 w-4" />
|
||||
<AlertTitle>No Data</AlertTitle>
|
||||
@@ -82,7 +82,7 @@ function RouteComponent() {
|
||||
</Alert>
|
||||
<div className="mt-6">
|
||||
<Link to="/home">
|
||||
<Button variant="outline">
|
||||
<Button variant="outline" className="w-full sm:w-auto">
|
||||
<ArrowLeft className="mr-2 h-4 w-4" />
|
||||
Back to Home
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user