Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Harley committed Nov 9, 2021
1 parent fa950a8 commit 683cef4
Show file tree
Hide file tree
Showing 42 changed files with 993 additions and 234 deletions.
72 changes: 72 additions & 0 deletions components/Email.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
export function Email() {
return (
<div className="bg-white">
<div className="relative sm:py-16">
<div className="mx-auto max-w-md px-4 sm:max-w-3xl sm:px-6 lg:max-w-7xl lg:px-8">
<div className="relative rounded-2xl px-6 py-10 bg-indigo-600 overflow-hidden shadow-xl sm:px-12 sm:py-20">
<div
aria-hidden="true"
className="absolute inset-0 -mt-72 sm:-mt-32 md:mt-0"
>
<svg
className="absolute inset-0 h-full w-full"
preserveAspectRatio="xMidYMid slice"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 1463 360"
>
<path
className="text-indigo-500 text-opacity-40"
fill="currentColor"
d="M-82.673 72l1761.849 472.086-134.327 501.315-1761.85-472.086z"
/>
<path
className="text-indigo-700 text-opacity-40"
fill="currentColor"
d="M-217.088 544.086L1544.761 72l134.327 501.316-1761.849 472.086z"
/>
</svg>
</div>
<div className="relative">
<div className="sm:text-center">
<h2 className="text-3xl font-extrabold text-white tracking-tight sm:text-4xl">
Get notified of new airdrops
</h2>
<p className="mt-6 mx-auto max-w-2xl text-lg text-indigo-200">
Submit your email below and we'll let you know when a new drop
happens
</p>
</div>
<form action="#" className="mt-12 sm:mx-auto sm:max-w-lg sm:flex">
<div className="min-w-0 flex-1">
<label htmlFor="cta-email" className="sr-only">
Email address
</label>
<input
id="cta-email"
type="email"
className="block w-full border border-transparent rounded-md px-5 py-3 text-base text-gray-900 placeholder-gray-500 shadow-sm focus:outline-none focus:border-transparent focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-indigo-600"
placeholder="Enter your email"
/>
</div>
<div className="mt-4 sm:mt-0 sm:ml-3">
<button
type="submit"
className="block w-full rounded-md border border-transparent px-5 py-3 bg-indigo-500 text-base font-medium text-white shadow hover:bg-indigo-400 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-indigo-600 sm:px-10"
>
Notify me
</button>
</div>
</form>
<div className="flex items-center justify-center pt-8">
<a href="/" target="_blank" className="text-white underline">
Want to register your airdrop?
</a>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
5 changes: 5 additions & 0 deletions components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from "react";

export const Footer = () => {
return <footer></footer>;
};
5 changes: 5 additions & 0 deletions components/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from "react";

export const Header = () => {
return <header></header>;
};
313 changes: 313 additions & 0 deletions components/Table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,313 @@
import { Fragment, useState } from "react";
import { Menu, Transition } from "@headlessui/react";
import {
ArchiveIcon,
ArrowCircleRightIcon,
ChevronDownIcon,
DuplicateIcon,
HeartIcon,
PencilAltIcon,
TrashIcon,
UserAddIcon,
} from "@heroicons/react/solid";
import { capitalise, classNames } from "../utils";
import { Airdrop } from "../interfaces";

import RawAirdrops from "../data/drops.json";

const now = Date.now();

enum Status {
Active = "active",
Inactive = "Inactive",
Upcoming = "Upcoming",
All = "All",
}

const getStatus = (startDate: string, endDate?: string) => {
const start = new Date(startDate);
const end = endDate ? new Date(endDate) : undefined;

if (end && end.getTime() < now) {
return Status.Inactive;
}

if (start.getTime() > now) {
return Status.Upcoming;
}

return Status.Active;
};

const airdrops = RawAirdrops.map((d) => ({
...d,
startDate: new Date(d.startDate),
endDate: d.endDate ? new Date(d.endDate) : undefined,
status: getStatus(d.startDate, d.endDate),
})).sort((a, b) => a.startDate.getTime() - b.startDate.getTime());

console.log(airdrops);

const networks: string[] = [
...new Set(
Object.values(airdrops).reduce(
(accum: string[], drop) => [...accum, drop.network],
[]
)
),
];

export function Table() {
const [network, setNetwork] = useState<string | null>(null);
const [status, setStatus] = useState(Status.Upcoming);

const filtered = airdrops.filter((d) => {
const checks = [
() => {
if (status === Status.All) {
return true;
}
return d.status === status;
},
() => {
if (!network) {
return true;
}

return d.network === network;
},
];

return checks.every((fn) => fn());
});

return (
<div className="space-y-4">
<div className="flex justify-end space-x-4">
<Menu as="div" className="relative inline-block text-left">
<div>
<Menu.Button className="inline-flex justify-center w-full rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-indigo-500">
{capitalise(status.toString())}
<ChevronDownIcon
className="-mr-1 ml-2 h-5 w-5"
aria-hidden="true"
/>
</Menu.Button>
</div>

<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 divide-y divide-gray-100 focus:outline-none">
<div className="py-1">
{Object.values(Status).map((s) => (
<Menu.Item onClick={() => setStatus(s)}>
{({ active }) => (
<a
className={classNames(
s === status
? "bg-gray-100 text-gray-900 cursor-default"
: "text-gray-700 hover:cursor-pointer",
"group flex items-center px-4 py-2 text-sm"
)}
>
<PencilAltIcon
className="mr-3 h-5 w-5 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
{capitalise(s)}
</a>
)}
</Menu.Item>
))}
</div>
{/* <div className="py-1">
<Menu.Item>
{({ active }) => (
<a
href="#"
className={classNames(
active ? "bg-gray-100 text-gray-900" : "text-gray-700",
"group flex items-center px-4 py-2 text-sm"
)}
>
<TrashIcon
className="mr-3 h-5 w-5 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
Delete
</a>
)}
</Menu.Item>
</div> */}
</Menu.Items>
</Transition>
</Menu>

<Menu as="div" className="relative inline-block text-left">
<div>
<Menu.Button className="inline-flex justify-center w-full rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-indigo-500">
{network ? capitalise(network) : "Network"}
<ChevronDownIcon
className="-mr-1 ml-2 h-5 w-5"
aria-hidden="true"
/>
</Menu.Button>
</div>

<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 divide-y divide-gray-100 focus:outline-none">
<div className="py-1">
{networks.map((n) => (
<Menu.Item onClick={() => setNetwork(n)}>
{({ active }) => (
<a
className={classNames(
n === network
? "bg-gray-100 text-gray-900 cursor-default"
: "text-gray-700 hover:cursor-pointer",
"group flex items-center px-4 py-2 text-sm"
)}
>
<PencilAltIcon
className="mr-3 h-5 w-5 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
{capitalise(n)}
</a>
)}
</Menu.Item>
))}
</div>
{/* <div className="py-1">
<Menu.Item>
{({ active }) => (
<a
href="#"
className={classNames(
active ? "bg-gray-100 text-gray-900" : "text-gray-700",
"group flex items-center px-4 py-2 text-sm"
)}
>
<TrashIcon
className="mr-3 h-5 w-5 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
Delete
</a>
)}
</Menu.Item>
</div> */}
</Menu.Items>
</Transition>
</Menu>
</div>

<div className="flex flex-col">
<div className="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div className="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
<div className="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Name
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Date
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Status
</th>
<th scope="col" className="relative px-6 py-3">
<span className="sr-only">Edit</span>
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{filtered.map((drop) => (
<tr key={`${drop.network}-${drop.token}`}>
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center">
<div className="flex-shrink-0 h-10 w-10">
<img
className="h-10 w-10 rounded-full"
src={`/images/${drop.network}.png`}
alt=""
/>
</div>
<div className="ml-4">
<div className="text-sm font-medium text-gray-900">
{capitalise(drop.network)}
</div>
<div className="text-sm text-gray-500">
${drop.token}
</div>
</div>
</div>
</td>

<td className="px-6 py-4 whitespace-nowrap">
<span
className={`px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${
drop.status === Status.Active &&
"bg-green-100 text-green-800"
} ${
drop.status === Status.Inactive &&
"bg-red-100 text-red-800"
} ${
drop.status === Status.Upcoming &&
"bg-blue-100 text-blue-800"
}`}
>
{capitalise(drop.status)}
</span>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="text-sm text-gray-900">
{drop.startDate.toDateString()}
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<a
href={drop.claimLink || drop.homeLink}
target="_blank"
className="text-indigo-600 hover:text-indigo-900"
>
Link
</a>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
);
}
Loading

0 comments on commit 683cef4

Please sign in to comment.