Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: event page for keploy with mock data #95

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions app/(default)/event/_components/eventheader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@

import { cn } from '@/lib/utils';
import { UsersIcon } from '@heroicons/react/24/solid'
import { HoverBorderGradient } from '@/components/ui/hover-border-gradient';
import React from 'react'

function EventHeader() {
return (
<header className="mb-12 h-full">
<div className="text-center mb-8 bg-gradient-to-r from-yellow-500 via-orange-500 to-yellow-500 p-8 rounded-lg text-white">
<HoverBorderGradientChip className="mb-4 bg-opacity-20 backdrop-filter backdrop-blur-lg">
<p className="flex items-center">
<UsersIcon className="mr-2 size-4" />
Events
</p>
</HoverBorderGradientChip>
<h2 className="mb-4 text-6xl font-bold">
Events
</h2>
<p className="max-w-3xl mx-auto text-lg font-medium">
Explore Keploy events and webinars. Learn from each other, move forward together, and celebrate what’s next. Whether you’re a developer, architect, tester, community manager, or something in-between, you’ll find something here.
</p>
</div>
</header>
)
}


function HoverBorderGradientChip({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) {
return (
<div className={cn('flex justify-center text-center', className)}>
<HoverBorderGradient
containerClassName="rounded-full"
as="button"
className="dark:bg-black bg-white text-black dark:text-white flex items-center space-x-2"
>
{children}
</HoverBorderGradient>
</div>
);
}

export default EventHeader
111 changes: 111 additions & 0 deletions app/(default)/event/_components/header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
"use client";

import React, { useState, useEffect } from "react";
import Link from "next/link";
import MobileMenu from "@/components/ui/mobile-menu";
import { FaSlack } from "react-icons/fa";
import { StarIcon } from "@heroicons/react/24/solid";
import CountingNumbers from "@/components/utils/countingNumbers";

export default function Header() {
const [top, setTop] = useState<boolean>(true);
const [starsCount, setStarsCount] = useState<number>(0);

// detect whether user has scrolled the page down by 10px
const scrollHandler = () => {
window.pageYOffset > 10 ? setTop(false) : setTop(true);
};

useEffect(() => {
scrollHandler();
window.addEventListener("scroll", scrollHandler);
return () => {
window.removeEventListener("scroll", scrollHandler);
};
}, []);

useEffect(() => {
const fetchStarsCount = async () => {
try {
const response = await fetch(
"https://api.github.com/repos/keploy/keploy"
);
if (response.ok) {
const data = await response.json() as { stargazers_count: number };
const stars = data.stargazers_count;
return stars;
} else {
console.error("Failed to fetch stars count", response.statusText);
return 0; // Return a default value in case of error
}
} catch (error) {
console.error("Error fetching stars count:", error);
return 0; // Return a default value in case of error
}
};

void fetchStarsCount().then(setStarsCount);
}, []);

return (
<header
className={`fixed w-full z-30 bg-white transition duration-300 ease-in-out ${!top ? "shadow-lg" : ""}`}
>
<div className="container mx-auto px-5 sm:px-6">
<div className="flex items-center justify-between h-16 md:h-20">
{/* Site branding */}
<div className="shrink-0 mr-4">
<Link href="/" className="flex items-center">
{/* <Image src="/images/logo.png" width={40} height={40} alt="Keploy Logo" /> */}
<span className="ml-2 text-xl font-bold text-gray-900">Keploy</span>
</Link>
</div>

{/* Desktop navigation */}
<nav className="hidden md:flex md:grow">
<div className="flex grow justify-end flex-wrap items-center">
<div className="border border-primary-400 rounded-md overflow-hidden p-2.5 border-opacity-40 relative transition-all group">
{/* Sliding effect span */}
<span className="absolute right-0 -mt-12 h-32 w-8 translate-x-12 rotate-12 bg-orange-500 opacity-10 transition-transform duration-1000 ease-out group-hover:translate-x-[-400%]" />

<Link
className="flex items-center gap-2 text-sm text-primary-400 font-extrabold transition-colors hover:text-primary-500"
target="_blank"
rel="noopener noreferrer"
aria-label="Keploy Github Repo"
data-radix-collection-item=""
href="https://www.github.com/keploy/keploy"
>
<svg
className="h-5 w-5"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
>
<title>Github Logo</title>
<path
d="M8 .2C3.6.2 0 3.8 0 8c0 3.5 2.3 6.5 5.5 7.6.4.1.5-.2.5-.4V14c-2.2.5-2.7-1-2.7-1-.4-.9-.9-1.2-.9-1.2-.7-.5.1-.5.1-.5.8.1 1.2.8 1.2.8.7 1.3 1.9.9 2.3.7.1-.5.3-.9.5-1.1-1.8-.2-3.6-.9-3.6-4 0-.9.3-1.6.8-2.1-.1-.2-.4-1 .1-2.1 0 0 .7-.2 2.2.8.6-.2 1.3-.3 2-.3s1.4.1 2 .3c1.5-1 2.2-.8 2.2-.8.4 1.1.2 1.9.1 2.1.5.6.8 1.3.8 2.1 0 3.1-1.9 3.7-3.7 3.9.3.4.6.9.6 1.6v2.2c0 .2.1.5.6.4 3.2-1.1 5.5-4.1 5.5-7.6-.1-4.4-3.7-8-8.1-8z"
fill="currentColor"
fillRule="evenodd"
/>
</svg>
<span className="text-gradient-500 opacity-30 hover:text-primary-500"> | </span>
<span className="text-base flex gap-1">
<StarIcon className="size-4 text-yellow-300 transition-all duration-300 group-hover:filter group-hover:drop-shadow-[0_0_2px_#FFD700]" />
</span>
<span className="text-base flex gap-1"> <CountingNumbers className="" /></span>
</Link>
</div>
<Link href="https://forms.gle/1GapWjqvTr82NHbr5"
className="flex flex-row items-center gap-2 px-4 py-2 rounded-md text-gray-200 bg-green-800 ml-3" target="_blank">
<FaSlack />
<span>Join Slack</span>
</Link>
</div>
</nav>

<MobileMenu starsCount={starsCount} />
</div>
</div>
</header>
);
}
94 changes: 94 additions & 0 deletions app/(default)/event/_data/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
export const events: EventType[] = [
{
id: 1,
title: "Keploy Meetup",
subtitle: "Keploy Meetup",
description: "Keploy Meetup",
startsAt: "2024-01-01",
duration: 60,
tags: ["Keploy", "Meetup"],
registerURL: "https://keploy.io",
createdAt: "2024-01-01",
updatedAt: "2024-01-01",
publishedAt: "2024-01-01",
banner: {
url: "https://keploy.io",
width: 100,
height: 100,
}
},
{
id: 1,
title: "Keploy Meetup",
subtitle: "Keploy Meetup",
description: "Keploy Meetup",
startsAt: "2024-01-01",
duration: 60,
tags: ["Keploy", "Meetup"],
registerURL: "https://keploy.io",
createdAt: "2024-01-01",
updatedAt: "2024-01-01",
publishedAt: "2024-01-01",
banner: {
url: "https://keploy.io",
width: 100,
height: 100,
}
},
{
id: 1,
title: "Keploy Meetup",
subtitle: "Keploy Meetup",
description: "Keploy Meetup",
startsAt: "2024-01-01",
duration: 60,
tags: ["Keploy", "Meetup"],
registerURL: "https://keploy.io",
createdAt: "2024-01-01",
updatedAt: "2024-01-01",
publishedAt: "2024-01-01",
banner: {
url: "https://keploy.io",
width: 100,
height: 100,
}
},
{
id: 1,
title: "Keploy Meetup",
subtitle: "Keploy Meetup",
description: "Keploy Meetup",
startsAt: "2024-01-01",
duration: 60,
tags: ["Keploy", "Meetup"],
registerURL: "https://keploy.io",
createdAt: "2024-01-01",
updatedAt: "2024-01-01",
publishedAt: "2024-01-01",
banner: {
url: "https://keploy.io",
width: 100,
height: 100,
}
}
]


export interface EventType {
id: number;
title: string;
subtitle: string;
description: string;
startsAt: string;
duration: number;
tags: string[];
registerURL: string | null;
createdAt: string;
updatedAt: string;
publishedAt: string;
banner: {
url: string;
width: number;
height: number;
};
}
36 changes: 36 additions & 0 deletions app/(default)/event/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Header from './_components/header'

import { Inter, Architects_Daughter } from 'next/font/google'


const inter = Inter({
subsets: ['latin'],
variable: '--font-inter',
display: 'swap'
})


const architects_daughter = Architects_Daughter({
subsets: ['latin'],
variable: '--font-architects-daughter',
weight: '400',
display: 'swap'
})

export const metadata = {
title: "Events | Keploy",
description: "Keploy is your open-source, developer-centric backend testing tool. It makes backend testing easy and productive for engineering teams. Plus, it's easy-to-use, powerful and extensible. 🛠️Keploy creates test cases and data mocks/stubs from user-traffic by recording API calls and DB queries, significantly speeding up releases and enhancing reliability. 📈"
}

export default function EventLayout({ children, }: { children: React.ReactNode }) {
return (
<html lang="en">
<body className={`${inter.variable} ${architects_daughter.variable} font-inter antialiased tracking-tight`}>
<Header />
<div className="flex flex-col min-h-screen overflow-hidden container mx-auto">
{children}
</div>
</body>
</html>
)
}
83 changes: 83 additions & 0 deletions app/(default)/event/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"use client"

import React from 'react'
import EventHeader from './_components/eventheader'
import Button from '@mui/material/Button'

import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { CalendarIcon, ClockIcon, } from '@heroicons/react/24/solid'
import Image from 'next/image'
import Link from 'next/link'

import { events } from './_data/events'

function EventPage() {
return (
<div className='min-h-screen mt-20 container'>
<div className='container mx-auto px-4 py-12'>
<EventHeader />
<div className="space-y-12">
<section>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{events.map((event, index) => (
<Card
key={index}
className="group overflow-hidden rounded-lg shadow-lg transition-all duration-300 hover:shadow-xl flex flex-col h-full"
>
<div className="relative h-52 overflow-hidden">
<Image
src={`https://wsrv.nl/?url=${event.banner.url}`}
alt={event.title}
layout="fill"
objectFit="cover"
className="transition-transform duration-300 group-hover:scale-105"
/>
</div>
<CardHeader>
<CardTitle className="text-2xl font-bold">
{event.title}
</CardTitle>
<CardDescription className="text-sm text-gray-400 truncate">
{event.subtitle}
</CardDescription>
</CardHeader>
<CardContent className="flex-grow space-y-2">
<div className="flex items-center text-sm">
<CalendarIcon className="mr-2 h-4 w-4 text-gray-500" />
<span>
{new Date(event.startsAt).toLocaleString()}
</span>
</div>
<div className="flex items-center text-sm">
<ClockIcon className="mr-2 h-4 w-4 text-gray-500" />
<span>{event.duration} minutes</span>
</div>
<div className="flex flex-wrap gap-2">
{event.tags.slice(0, 3).map((tag, index) => (
<Badge key={index} className="mr-2">
{tag}
</Badge>
))}
</div>
</CardContent>
<CardFooter className="mt-auto">
<button
className="w-full bg-yellow-400 hover:bg-yellow-500 py-2 px-4 rounded-md"
>
<Link href={event.registerURL || '#'} target="_blank">
Register Now
</Link>
</button>
</CardFooter>
</Card>
))}
</div>
</section>
</div>
</div>
</div>
)
}

export default EventPage
Loading