Skip to content

Commit

Permalink
Event routing works fully and some formatting changes throughout site.
Browse files Browse the repository at this point in the history
  • Loading branch information
zeshankhatri committed Nov 13, 2023
1 parent c965a81 commit efd1311
Show file tree
Hide file tree
Showing 15 changed files with 177 additions and 101 deletions.
3 changes: 3 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ await import("./src/env.mjs");
/** @type {import("next").NextConfig} */
const config = {
reactStrictMode: true,
images: {
domains: ["res.cloudinary.com"],
},

/**
* If you are using `appDir` then you must comment the below `i18n` config out.
Expand Down
22 changes: 11 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions prisma/migrations/20231110072429_/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-- CreateTable
CREATE TABLE "Event" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" TEXT NOT NULL,
"description" TEXT NOT NULL,
"time" DATETIME NOT NULL,
"location" TEXT NOT NULL,
"picture" TEXT NOT NULL,
"program" TEXT NOT NULL,
"rsvpLink" TEXT NOT NULL
);

-- CreateTable
CREATE TABLE "JobPosting" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"image" TEXT NOT NULL,
"title" TEXT NOT NULL,
"company" TEXT NOT NULL,
"jobType" TEXT NOT NULL,
"jobPosition" TEXT NOT NULL,
"jobLocation" TEXT NOT NULL,
"date" TEXT NOT NULL,
"url" TEXT NOT NULL
);
3 changes: 3 additions & 0 deletions prisma/migrations/migration_lock.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "sqlite"
2 changes: 1 addition & 1 deletion prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ model Event {
time DateTime
location String
picture String // Assuming this is a URL or file path to the image
tag String
program String
rsvpLink String
}

Expand Down
7 changes: 7 additions & 0 deletions prisma/seed.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { events } from "../src/Data/eventsData";
import { jobPostings } from "../src/Data/jobPostingsData";
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

async function main() {
for (const event of events) {
await prisma.event.create({
data: event,
});
}

for (const jobPosting of jobPostings) {
await prisma.jobPosting.create({
data: jobPosting,
Expand Down
24 changes: 24 additions & 0 deletions src/Data/eventsData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export const events = [
{
name: "Interview Prep: Graphs",
description:
"Learn about the fundamentals of graphs to prepare for technical interviews!",
time: new Date("2023-11-08T21:00:00.000Z"),
location: "CBC 155",
picture:
"https://res.cloudinary.com/dh6y8bufo/image/upload/v1699911150/init-dashboard/Interview%20Prep%20Image.avif",
program: "Reach",
rsvpLink: "https://lu.ma/p31somhk",
},
{
name: "Design: Build a Portfolio",
description:
"Learn to create projects for your portfolio and gain UI/UX experience!",
time: new Date("2023-10-26T20:00:00.000Z"),
location: "CASE 132",
picture:
"https://res.cloudinary.com/dh6y8bufo/image/upload/v1699914651/init-dashboard/Mock%20Interview.jpg",
program: "Explore",
rsvpLink: "https://lu.ma/pzc4g76u",
},
];
54 changes: 35 additions & 19 deletions src/components/EventCard.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,68 @@
import Image from "next/image";
import initLogo from "../assets/init.png";
import type { EventCard } from "../interfaces/EventCard.interface";

export default function EventCard({
name,
description,
picture,
time,
location,
tag,
program,
rsvpLink,
}: EventCard) {
const date = time.toLocaleDateString("en-us", {
weekday: "short",
month: "long",
day: "numeric",
});
const realTime = time.toLocaleTimeString("en-us", {
hour: "numeric",
minute: "numeric",
timeZoneName: "short",
});

return (
<div className="group flex h-full flex-col rounded-xl border border-gray-200 bg-white shadow-sm dark:border-gray-700 dark:bg-slate-900 dark:shadow-slate-700/[.7]">
<div className="relative h-52 overflow-hidden rounded-t-xl sm:h-56">
<div className="group flex h-full flex-col rounded-sm border border-zinc-600 bg-zinc-900 shadow-lg shadow-zinc-900">
<div className="relative h-52 overflow-hidden rounded-t-sm sm:h-56">
<Image
// Add picture of event here
src={initLogo}
src={picture}
alt={`${name} Event Image`}
width={1000}
height={1000}
className="absolute h-full w-full object-cover"
/>
</div>

<div className="flex flex-grow flex-col justify-between p-4 md:p-6">
<div>
<span className="mb-1 block text-xs font-semibold uppercase text-blue-600 dark:text-blue-500">
{tag}
<span
className={`mb-1 block text-xs font-semibold uppercase ${
program === "ShellHacks" || program === "General"
? "text-primary"
: `text-${program.toLowerCase()}`
}`}
>
{program}
</span>
<h3 className="text-lg font-semibold text-gray-800 dark:text-gray-300 dark:hover:text-white sm:text-xl">
<h3 className="text-lg font-semibold text-gray-300 sm:text-xl">
{name}
</h3>
<p className="sm:text-md mt-2 text-sm text-gray-500">{description}</p>
<div className="mt-2 text-sm sm:mt-4">
<p className="text-gray-400">{time.toTimeString()}</p>

<p className="text-gray-400">{location}</p>
<div className="mt-2 space-y-1 text-sm sm:mt-4">
<p className="text-gray-400">{date}</p>
<p className="text-xs text-gray-400">
{location} | {realTime}
</p>
</div>
</div>

<div className="mt-4 flex divide-x divide-gray-200 border-t border-gray-200 dark:divide-gray-700 dark:border-gray-700">
<div className="mt-4 flex">
<a
className="inline-flex w-full items-center justify-center gap-2 rounded-bl-xl bg-white px-4 py-3 text-sm font-medium text-gray-700 shadow-sm transition-all hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-600 focus:ring-offset-2 focus:ring-offset-white dark:border-gray-700 dark:bg-slate-900 dark:text-gray-400 dark:hover:bg-slate-800 dark:hover:text-white dark:focus:ring-offset-gray-800"
className="inline-flex w-full items-center justify-center gap-2 rounded-md bg-primary_yellow px-3 py-2 text-xs font-medium text-gray-700 shadow-sm transition-all hover:bg-light_yellow focus:outline-none focus:ring-2 focus:ring-light_yellow sm:rounded-lg sm:px-4 sm:py-3 sm:text-sm"
href={rsvpLink}
target="_blank"
>
RSVP Now
</a>
<a className="inline-flex w-full items-center justify-center gap-2 rounded-br-xl bg-white px-4 py-3 text-sm font-medium text-gray-700 shadow-sm transition-all hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-600 focus:ring-offset-2 focus:ring-offset-white dark:border-gray-700 dark:bg-slate-900 dark:text-gray-400 dark:hover:bg-slate-800 dark:hover:text-white dark:focus:ring-offset-gray-800">
View More Details
</a>
</div>
</div>
</div>
Expand Down
45 changes: 29 additions & 16 deletions src/components/EventModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,24 @@ import { Modal } from "flowbite-react";
import { useForm } from "react-hook-form";
import Image from "next/image";
import axios from "axios";
import { api } from "~/utils/api";

interface IFormInputs {
name: string;
program: string;
picture: string;
description: string;
location: string;
dateTime: Date;
time: Date;
rsvpLink: string;
}

export default function EventModal() {
const [openModal, setOpenModal] = useState(false);
const [image, setImage] = useState<string | ArrayBuffer | null>(null);
const { register, handleSubmit } = useForm<IFormInputs>();

const [filename, setFilename] = useState("");
const { register, handleSubmit, reset } = useForm<IFormInputs>();
const createEvent = api.events.create.useMutation();
const CLOUDINARY_NAME = process.env.NEXT_PUBLIC_CLOUD_NAME;

const fileChangeHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
Expand All @@ -30,13 +33,18 @@ export default function EventModal() {

if (event.target.files![0]) {
reader.readAsDataURL(event.target.files![0] as Blob);
const filenameWithExt = event.target.files![0].name;
setFilename(filenameWithExt.substring(0, filenameWithExt.indexOf("."))); //removes extension from filename
}
};

const uploadHandler = async () => {
const onSubmit = async (data: IFormInputs) => {
const formData = new FormData();
formData.append("file", image as string);
formData.append("upload_preset", "init_dashboard_upload");
formData.append("public_id", filename);
formData.append("filename_override", "true");
let secure_url = "";

try {
const res = await axios.post(
Expand All @@ -47,26 +55,29 @@ export default function EventModal() {
},
);

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (res.data.secure_url) {
alert("Image uploaded successfully!");
setImage(null);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
secure_url = res.data.secure_url;

if (secure_url) {
console.log("Image uploaded successfully!");
}
} catch (e) {
console.assert(e, "Error, image not uploaded!");
console.log(e, "Error, image not uploaded!");
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
};
const dateObject = new Date(data.time);
data = { ...data, picture: secure_url, time: dateObject };

const onSubmit = (data: IFormInputs) => {
console.log(data);
createEvent.mutate(data);
setOpenModal(false);
setImage(null);
reset(); //reset method from react-hook-form; resets form fields
};

return (
<>
<button
className="hover:bg-light-yellow inline-flex w-full items-center justify-center gap-2 rounded-md bg-primary_yellow px-4 py-3 text-sm font-semibold text-black transition-all hover:bg-light_yellow focus:outline-none focus:ring-2 focus:ring-light_yellow md:w-auto"
className="hover:bg-light-yellow inline-flex w-full items-center justify-center gap-2 rounded-md bg-primary_yellow px-3 py-2 text-sm font-semibold text-black transition-all hover:bg-light_yellow focus:outline-none focus:ring-2 focus:ring-light_yellow md:w-auto lg:px-4 lg:py-3"
type="button"
onClick={() => setOpenModal(true)}
>
Expand Down Expand Up @@ -137,10 +148,12 @@ export default function EventModal() {
>
<option className="italic">-- Select a Program --</option>
<option>Build</option>
<option>Code</option>
<option>Discover</option>
<option>Explore</option>
<option>General</option>
<option>Hack</option>
<option>Ignite</option>
<option>Industry</option>
<option>Launch</option>
<option>Reach</option>
<option>ShellHacks</option>
Expand Down Expand Up @@ -249,7 +262,7 @@ export default function EventModal() {
Date and Time
</label>
<input
{...register("dateTime")}
{...register("time")}
type="datetime-local"
className="block w-full rounded-sm text-xs text-primary shadow-sm focus:border-none focus:ring-light_yellow"
required
Expand Down
8 changes: 5 additions & 3 deletions src/components/ThisWeekCard.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Link from "next/link";

export default function ThisWeekCard() {
return (
<div className="mb-20 mt-20 w-full max-w-6xl gap-4 px-4 md:grid md:grid-cols-2 md:px-0">
Expand All @@ -7,12 +9,12 @@ export default function ThisWeekCard() {
This Week
</h5>
<div className="mt-7 flex justify-center">
<a
href="<events />"
<Link
href="/events"
className="flex items-center rounded-lg bg-primary_yellow px-6 py-3.5 font-bold text-primary hover:bg-light_yellow focus:outline-none focus:ring-2 focus:ring-gray-600"
>
Register Now!
</a>
</Link>
</div>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/interfaces/EventCard.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ export interface EventCard {
id: number;
name: string;
description: string;
picture: string;
time: Date;
location: string;
// picture: string;
tag: string;
program: string;
rsvpLink: string;
}
Loading

0 comments on commit efd1311

Please sign in to comment.