forked from steakwallet/airdrops
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Alex Harley
committed
Nov 9, 2021
1 parent
fa950a8
commit 683cef4
Showing
42 changed files
with
993 additions
and
234 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import React from "react"; | ||
|
||
export const Footer = () => { | ||
return <footer></footer>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import React from "react"; | ||
|
||
export const Header = () => { | ||
return <header></header>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
); | ||
} |
Oops, something went wrong.