Skip to content

Commit

Permalink
feat: add glamp detail
Browse files Browse the repository at this point in the history
  • Loading branch information
patrikzita committed Mar 2, 2024
1 parent a4ec7f9 commit 5b947ef
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 20 deletions.
Binary file modified sqlite.db
Binary file not shown.
43 changes: 29 additions & 14 deletions src/components/PreviewCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,42 @@ import {
import { Glamp } from "@/generated/graphql";
import { cn } from "@/lib/utils";
import { formatDate } from "date-fns";
import Link from "next/link";
import { ParsedUrlQuery } from "querystring";

type CardProps = React.ComponentProps<typeof Card> & {
glamp: Glamp;
queryParams?: ParsedUrlQuery;
};

export function PreviewCard({ className, glamp, ...props }: CardProps) {
export function PreviewCard({
className,
glamp,
queryParams,
...props
}: CardProps) {
const linkHref = {
pathname: `/glamps/${glamp.id}`,
query: queryParams,
};

return (
<Card className={cn(className)} {...props}>
<CardHeader>
<CardTitle className={cn({ "text-yellow-600": glamp.isLuxury })}>
{glamp.title}
</CardTitle>
<CardDescription>{glamp.description}</CardDescription>
</CardHeader>
<CardContent className="grid gap-4"></CardContent>
<CardFooter>
<p>
{formatDate(new Date(glamp.availableFrom), "dd.MMMM yyyy")} -{" "}
{formatDate(new Date(glamp.availableTo), "dd.MMMM yyyy")}
</p>
</CardFooter>
<Link href={linkHref}>
<CardHeader>
<CardTitle className={cn({ "text-yellow-600": glamp.isLuxury })}>
{glamp.title}
</CardTitle>
<CardDescription>{glamp.description}</CardDescription>
</CardHeader>
<CardContent className="grid gap-4"></CardContent>
<CardFooter>
<p>
{formatDate(new Date(glamp.availableFrom), "dd.MMMM yyyy")} -{" "}
{formatDate(new Date(glamp.availableTo), "dd.MMMM yyyy")}
</p>
</CardFooter>
</Link>
</Card>
);
}
4 changes: 0 additions & 4 deletions src/components/SeachBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,10 @@ function SearchBar({ onSearch }: SearchBarProps) {
: { from: undefined, to: undefined };
return (
<FormItem className="flex flex-col">
<FormLabel>Date of birth</FormLabel>
<DateRange
selected={validDateRange}
onSelect={field.onChange}
/>
<FormDescription>
Your date of birth is used to calculate your age.
</FormDescription>
<FormMessage />
</FormItem>
);
Expand Down
14 changes: 14 additions & 0 deletions src/graphql/query/getGlamp.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
query getGlamp($glampId: Int) {
glamp(glampId: $glampId) {
id
title
description
type
price
availableFrom
availableTo
adultCapacity
childCapacity
isLuxury
}
}
15 changes: 14 additions & 1 deletion src/graphql/schema/glamps/glamps.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { db } from "@/db/db";
import { glamps as dbGlamps } from "@/db/schema";
import { and, count, eq, gte, lte } from "drizzle-orm";
import { Arg, Ctx, Float, Int, Query, Resolver } from "type-graphql";
import { Arg, Args, Ctx, Float, Int, Query, Resolver } from "type-graphql";
import { Glamp, GlampsResponse } from "./glamps";
import type { MyContext } from "@/pages/api/graphql";
import { z } from "zod";
Expand All @@ -21,6 +21,19 @@ export class GlampResolver {
return glamps;
}

@Query(() => Glamp)
async glamp(
@Arg("glampId", () => Int)
glampId: number
): Promise<Glamp> {
const glamp = await db
.select()
.from(dbGlamps)
.where(eq(dbGlamps.id, glampId));

return glamp[0];
}

@Query(() => GlampsResponse)
async searchGlamps(
@Arg("offset", () => Int) offset: number,
Expand Down
134 changes: 134 additions & 0 deletions src/pages/glamps/[glampId]/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { Shell } from "@/components/Shell";
import {
GetGlampDocument,
GetGlampQuery,
GetGlampQueryVariables,
useGetGlampQuery,
} from "@/generated/graphql";
import { addApolloState, initializeApollo } from "@/utils/apolloClient";
import { GetServerSidePropsContext } from "next";
import { useRouter } from "next/router";

import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { isDateRange } from "react-day-picker";
import { DateRange } from "@/components/DateRange";
import { z } from "zod";
import { searchParamsSchema } from "@/lib/validators/searchParams";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { toast } from "@/components/ui/use-toast";

const FormSchema = z.object({
dateRange: z.object({
from: z.date({ required_error: "A date of birth is required." }),
to: z.date({ required_error: "A date to is required" }),
}),
});

const GlampDetailPage = () => {
const router = useRouter();

const searchParamsResult = searchParamsSchema.safeParse(router.query);

let defaultValues = {
dateRange: {
from: undefined,
to: undefined,
},
isLuxury: false,
};

if (searchParamsResult.success) {
const { dateFrom, dateTo, isLuxury } = searchParamsResult.data;
defaultValues = {
dateRange: {
from: dateFrom ? new Date(dateFrom) : undefined,
to: dateTo ? new Date(dateTo) : undefined,
},
isLuxury,
};
}
const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema),
defaultValues,
});
function onSubmit(data: z.infer<typeof FormSchema>) {
toast({
title: "You submitted the following values:",
description: (
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
</pre>
),
});
}

const { glampId } = router.query;

const { data, loading } = useGetGlampQuery({
variables: {
glampId: Number(glampId),
},
});

if (loading) {
<div>loading</div>;
}

return (
<Shell>
<h1>{data.glamp.title}</h1>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="dateRange"
render={({ field }) => {
const validDateRange = isDateRange(field.value)
? field.value
: { from: undefined, to: undefined };
return (
<FormItem className="flex flex-col">
<DateRange
selected={validDateRange}
onSelect={field.onChange}
/>
<FormMessage />
</FormItem>
);
}}
/>

<Button type="submit">Submit</Button>
</form>
</Form>
</Shell>
);
};

export default GlampDetailPage;

export async function getServerSideProps(context: GetServerSidePropsContext) {
const apolloClient = initializeApollo({ context });

const { glampId } = context.query;

await apolloClient.query<GetGlampQuery, GetGlampQueryVariables>({
query: GetGlampDocument,
variables: {
glampId: Number(glampId),
},
});

return addApolloState(apolloClient, {
props: {},
});
}
6 changes: 5 additions & 1 deletion src/pages/glamps/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@ export default function GlampsSearchPage() {
<SearchBar onSearch={handleSearch} />
<div className="grid md:grid-cols-3 gap-3">
{data?.searchGlamps.glamps.map((glamp) => (
<PreviewCard key={glamp.id} glamp={glamp} />
<PreviewCard
key={glamp.id}
glamp={glamp}
queryParams={router.query}
/>
))}
</div>
</Shell>
Expand Down

0 comments on commit 5b947ef

Please sign in to comment.