Skip to content

Commit

Permalink
add dateRange to events
Browse files Browse the repository at this point in the history
  • Loading branch information
joelmturner committed Apr 16, 2024
1 parent 4e5f328 commit cf52536
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 7 deletions.
15 changes: 14 additions & 1 deletion db/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@ const Food = defineTable({
}
});

export const events = defineTable({
columns: {
id: column.number({primaryKey: true, unique: true}),
title: column.text(),
description: column.text(),
dateStart: column.text(),
dateEnd: column.text(),
url: column.text(),
type: column.text(),
year: column.number(),
}
});

export const user = defineTable( {
columns: {
id: column.text({primaryKey: true, notNull: true, unique: true}),
Expand Down Expand Up @@ -46,5 +59,5 @@ const list = defineTable({

// https://astro.build/db/config
export default defineDb( {
tables: { Food, user, session, list}
tables: { Food, user, session, list, events }
} );
62 changes: 59 additions & 3 deletions src/components/DataForm.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
$: data = null;
$: data = null as { eventDetails: any; food: any[] } | null;
$: status = "idle";
Expand Down Expand Up @@ -49,6 +49,40 @@
console.error("Failed to add data to db");
}
}
async function handleSubmitEventDetails(
event: SubmitEvent & { currentTarget: EventTarget & HTMLFormElement }
) {
const formData = new FormData(event.target);
const eventData = formData.get("data");
const { title, description, dateStart, dateEnd, url, year, type } =
JSON.parse(eventData);
status = "loading";
// Handle form submission logic here
const response = await fetch("/api/events/addDetails", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title,
description,
dateStart,
dateEnd,
url,
year,
type,
}),
});
if (response.ok) {
status = "Data added to db";
} else {
status = "Failed to add data to db";
console.error("Failed to add data to db");
}
}
</script>

<form on:submit|preventDefault={handleSubmitUrl} class="flex flex-col gap-3">
Expand All @@ -66,6 +100,7 @@
{/if}

{#if data}
<h3>Food</h3>
<form on:submit|preventDefault={handleSubmitData} class="flex flex-col gap-3">
<div class="flex flex-col gap-1">
<label for="year">Year</label>
Expand All @@ -91,12 +126,33 @@
</div>

<button type="submit" class="btn btn-primary max-w-xs">Add to db</button>
<input value={JSON.stringify(data)} hidden name="data" id="data" />
<input value={JSON.stringify(data.food)} hidden name="data" id="data" />
</form>

<h3>Event Details</h3>
<form
on:submit|preventDefault={handleSubmitEventDetails}
class="flex flex-col gap-3"
>
<input
type="hidden"
value={JSON.stringify(data.eventDetails)}
name="data"
id="name"
/>
<button type="submit" class="btn btn-primary max-w-xs">Add to db</button>
</form>

<div class="h-full max-h-96 w-full p-4 overflow-auto">
<pre><code>
{JSON.stringify(data.eventDetails, null, 2)}
</code></pre>
</div>

<div class="py-24" />
<div class="h-full max-h-96 w-full p-4 overflow-auto">
<pre><code>
{JSON.stringify(data, null, 2)}
{JSON.stringify(data.food, null, 2)}
</code></pre>
</div>
{/if}
20 changes: 20 additions & 0 deletions src/pages/api/events/addDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { APIContext } from "astro";
import { db, events } from "astro:db";

export async function POST(context: APIContext): Promise<Response> {
if (!context.locals.session) {
return new Response(null, {
status: 401,
});
}

// add event details to events table
const data = await context.request.json();
const event = await db.insert(events).values(data).run();

if (event) {
return new Response(null, { status: 200 });
} else {
return new Response(null, { status: 400 });
}
}
31 changes: 30 additions & 1 deletion src/pages/api/fetchDataFromSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,36 @@ const getPages = async (eventUrls: string[]) => {
return await Promise.all(events);
};

// Function to parse the date from the given text
function parseDates(dateStr: string): { dateStart: Date; dateEnd: Date } {
const dateEndText = dateStr.split("through ")[1]; // Extracts "April 21"
const currentYear = new Date().getFullYear(); // Gets the current year
const dateEnd = new Date(`${dateEndText}, ${currentYear}`); // Assumes the end date is within the current year

// dateStart is dateEnd minus 7 days
const dateStart = new Date(dateEnd);
dateStart.setDate(dateStart.getDate() - 6);

return { dateStart, dateEnd };
}

async function getEventDetails(baseUrl: string) {
const $ = await fetchData(baseUrl);
const title = $("header > h1").text().trim();
const dateText = $(".date-summary > span").text().trim();
const { dateStart, dateEnd } = parseDates(dateText);
const url = baseUrl;
const description = $(".descriptions > .description").text().trim();
const year = dateStart.getFullYear();
const types = ["sandwich", "nacho", "burger", "pizza"];
// check which type the title contains
const type = types.find(type => title.toLowerCase().includes(type));
return { title, dateStart, dateEnd, url, description, year, type };
}

const getEventUrls = async (baseUrl: string) => {
const $ = await fetchData(baseUrl);

const eventUrls: string[] = [];

$(".item-detail.event > .row > .col > a").each(function (index, element) {
Expand Down Expand Up @@ -95,9 +123,10 @@ export async function POST(context: APIContext): Promise<Response> {
console.log("Using cached data");
return new Response(JSON.stringify(cache));
}
const eventDetails = await getEventDetails(baseUrl);
const urls = await getEventUrls(baseUrl);
const eventData = await getPages(urls);

cache = eventData;
cache = { eventDetails, food: eventData };
return new Response(JSON.stringify(eventData));
}
8 changes: 8 additions & 0 deletions src/pages/pizza/[year].astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import Main from "@layouts/Main.astro";
import Footer from "@components/Footer.astro";
import CardGrid from "../../components/CardGrid.astro";
import {
formatter,
getEventDetails,
getFoodItems,
getLists,
getUniqueNeighborhoods,
Expand All @@ -15,6 +17,11 @@ const { year } = Astro.params;
const pizzas = await getFoodItems(year!, "pizza");
const neighborhoods = pizzas ? getUniqueNeighborhoods(pizzas) : [];
const lists = await getLists(Astro.locals?.user?.id);
const eventDetails = await getEventDetails(year!, "pizza");
const dateRange = eventDetails
? `${formatter.format(new Date(eventDetails.dateStart))} - ${formatter.format(new Date(eventDetails.dateEnd))} ${eventDetails.year}`
: null;
---

<Layout
Expand All @@ -23,6 +30,7 @@ const lists = await getLists(Astro.locals?.user?.id);
>
<Header />
<Main pageTitle={`Pizza ${year}`} neighborhoods={neighborhoods}>
{dateRange ? <h3>{dateRange}</h3> : null}
{pizzas && <CardGrid items={pizzas} lists={lists} />}
</Main>
<Footer />
Expand Down
11 changes: 11 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ export type FoodItem = {
type: "sandwich" | "nacho" | "burger" | "pizza";
};

export type EventsItem = {
id: string;
title: string;
description: string;
dateStart: string;
dateEnd: string;
url: string;
type: "sandwich" | "nacho" | "burger" | "pizza";
year: number;
};

export type ListItem = {
id: number;
name?: string;
Expand Down
19 changes: 17 additions & 2 deletions src/utils/collections.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Food, and, db, eq, list } from "astro:db";
import type { FoodItem, ListItem } from "types";
import { Food, and, db, eq, events, list } from "astro:db";
import type { EventsItem, FoodItem, ListItem } from "types";

export function getYearsFromData(data: { year: number }[]) {
const uniqueYears = new Set([...data.map(item => item.year)]);
Expand Down Expand Up @@ -49,3 +49,18 @@ export async function getFoodItems(
and(eq(Food.year, parseInt(year)), eq(Food.type, type))
)) as unknown as FoodItem[];
}

export async function getEventDetails(year: string, type: EventsItem["type"]) {
return (
await db
.select()
.from(events)
.where(and(eq(events.year, parseInt(year)), eq(events.type, type)))
)?.[0] as unknown as EventsItem;
}

export const formatter = new Intl.DateTimeFormat("en-US", {
month: "long", // full name of the month
day: "numeric", // numeric day of the month
timeZone: "UTC", // important to ensure correct day regardless of local timezone
});

0 comments on commit cf52536

Please sign in to comment.