Skip to content

Commit

Permalink
Adds upcoming collection preview
Browse files Browse the repository at this point in the history
  • Loading branch information
maxwellfortney committed Oct 19, 2021
1 parent fb87ace commit 32acbdb
Show file tree
Hide file tree
Showing 13 changed files with 496 additions and 76 deletions.
1 change: 1 addition & 0 deletions components/Collection/SortController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export default function SortController() {
if (sortType !== sort) {
return (
<button
key={sortType}
onClick={() => {
setSort(sortType);
setIsOpen(false);
Expand Down
7 changes: 5 additions & 2 deletions components/Navbar/SearchPreview/SearchPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ export default function SearchPreview() {
}

useEffect(() => {
fetchSearchResults();
if (searchString.length > 0) {
fetchSearchResults();
}
}, [searchString]);

return (
Expand All @@ -36,7 +38,7 @@ export default function SearchPreview() {
unmountOnExit
>
<div
className="absolute flex w-full h-12 rounded-lg bg-moreLight"
className="absolute z-10 flex w-full h-12 rounded-lg bg-moreLight"
style={{ top: "calc(100% + 12px)" }}
>
<SwitchTransition>
Expand Down Expand Up @@ -65,6 +67,7 @@ export default function SearchPreview() {
(result: any) => {
return (
<ASearchResultRow
key={result.name}
collectionName={
result.name
}
Expand Down
176 changes: 176 additions & 0 deletions components/Upcoming/DayOfMonth.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import { useState } from "react";
import { SocialIcon } from "react-social-icons";
import { monthNames, rainbowGradient } from "../../utils/client";
import Modal from "../Modal/Modal";

import Link from "next/link";
import { LazyLoadImage } from "react-lazy-load-image-component";

interface IDayOfMonth {
dayOfMonth: number;
month: number;
collections: Array<any>;
}

export default function DayOfMonth({
dayOfMonth,
month,
collections,
}: IDayOfMonth) {
function createDayString() {
let ret = "";
let now = new Date();

if (month === now.getMonth()) {
if (dayOfMonth === now.getDate()) {
ret = "today";
} else if (dayOfMonth == now.getDate() + 1) {
ret = "tomorrow";
} else {
ret = dayOfMonth.toString();
}
} else {
ret = dayOfMonth.toString();
}

return ret;
}
return (
<div
className="flex flex-col w-full px-2 py-1 bg-white"
style={{ aspectRatio: "1" }}
>
<p
className="w-full pb-1 text-2xl font-extrabold border-black"
style={{ borderBottomWidth: "1px" }}
>
{createDayString()}
</p>
<div className="flex flex-col flex-1 w-full mt-1">
{collections.map((collection) => {
return (
<AnUpcomingPreview
key={collection.name}
collection={collection}
/>
);
})}
</div>
</div>
);
}

function AnUpcomingPreview({ collection }: any) {
const [modalOpen, setModalOpen] = useState(false);

const date = new Date(collection.listDate);

return (
<>
<Modal isOpen={modalOpen} onClose={() => setModalOpen(false)}>
<div
className={`z-10 p-4 flex flex-col justify-center rounded-lg overflow-hidden items-center w-11/12 md:w-2/3 lg:w-1/3 relative shadow-lg bg-white`}
>
<div className="flex justify-between w-full">
<p className="self-start text-3xl font-black">
{collection.name}
</p>
<div className="flex items-end mb-1">
{collection.websiteURL && (
<Link href={collection.websiteURL}>
<a
className="flex items-center justify-center ml-2 text-white transition-opacity duration-300 bg-blue-500 rounded-full hover:opacity-70"
style={{
width: "30px",
height: "30px",
}}
>
<svg
className="w-5 h-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</a>
</Link>
)}
{collection.twitterURL && (
<SocialIcon
url={collection.twitterURL}
target="_blank"
network="twitter"
fgColor="#FFFFFF"
style={{ height: 30, width: 30 }}
className="ml-2 transition-opacity duration-300 hover:opacity-70"
/>
)}
{collection.discordURL && (
<SocialIcon
url={collection.discordURL}
target="_blank"
network="discord"
fgColor="#FFFFFF"
className="ml-2 transition-opacity duration-300 hover:opacity-70"
style={{ height: 30, width: 30 }}
/>
)}
</div>
</div>
<p className="self-start mt-1 font-bold">
{monthNames[date.getMonth()]} {date.getDate()},{" "}
<span
className="font-bold text-transparent bg-clip-text"
style={{
backgroundImage: rainbowGradient(
date.getHours() + date.getMinutes() / 60,
0,
24
),
}}
>
{date.getHours()}:
{date.getMinutes().toString().padEnd(2, "0")}
</span>
</p>

{collection.previewImages && (
<div className="grid w-full grid-cols-2 mt-3">
{collection.previewImages.map((image: string) => {
return (
<LazyLoadImage key={image} src={image} />
);
})}
</div>
)}
</div>
</Modal>
<button
onClick={() => setModalOpen(true)}
key={collection.name}
className="flex justify-between w-full px-1 transition-colors duration-300 rounded-md hover:bg-slightDark hover:text-white"
>
<p className="font-medium">{collection.name}</p>
<p
className="font-bold text-transparent bg-clip-text"
style={{
backgroundImage: rainbowGradient(
date.getHours() + date.getMinutes() / 60,
0,
24
),
}}
>
{date.getHours()}:
{date.getMinutes().toString().padEnd(2, "0")}
</p>
</button>
</>
);
}
35 changes: 35 additions & 0 deletions components/Upcoming/Month.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { monthNames } from "../../utils/client";
import DayOfMonth from "./DayOfMonth";

interface IMonth {
month: number;
days: Array<any>;
}

export default function Month({ month, days }: IMonth) {
return (
<>
<h2 className="mb-1 text-lg font-black text-white">
{monthNames[month]}
</h2>
<div
className="grid w-11/12 gap-3 mb-10"
style={{
gridTemplateColumns:
"repeat(auto-fill, minmax(210px, 1fr))",
}}
>
{days.map((dayOfMonth: any) => {
return (
<DayOfMonth
key={dayOfMonth.dayOfMonth}
dayOfMonth={dayOfMonth.dayOfMonth}
month={dayOfMonth.month}
collections={dayOfMonth.collections}
/>
);
})}
</div>
</>
);
}
6 changes: 4 additions & 2 deletions models/Collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,28 @@ import mongoose, { Document, model, Model, Schema } from "mongoose";

export interface ICollection extends Document {
name: string;
externalURL: string;
websiteURL?: string;
discordURL?: string;
twitterURL?: string;
totalSupply: number;
highestMeanPercentage: number;
lowestMeanPercentage: number;
listDate?: number;
mintPrice?: number;
previewImages?: Array<string>;
}

export const CollectionSchema: Schema = new mongoose.Schema({
name: String,
externalURL: String,
websiteURL: { type: String, required: false },
discordURL: { type: String, required: false },
twitterURL: { type: String, required: false },
totalSupply: Number,
highestMeanPercentage: Number,
lowestMeanPercentage: Number,
listDate: { type: Number, required: false },
mintPrice: { type: Number, required: false },
previewImages: { type: [String], required: false },
});

export const Collection: Model<ICollection> =
Expand Down
50 changes: 4 additions & 46 deletions pages/api/collections/[collectionName]/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,62 +9,20 @@ export default async function handler(
res: NextApiResponse
) {
const collectionName = req.query.collectionName as string;
const page = parseInt(req.query.page as string) || 0;
const perPage = parseInt(req.query.perPage as string) || 25;
const idFilter = (req.query.idFilter as string) || "";
const sort = (req.query.sort as string) || "rank";

await dbConnect();

console.log(parseSortString(sort));
const collection = await Collection.findOne({ name: collectionName });

let nfts = [];
if (idFilter.length > 0) {
nfts = await NFT.find(
{
collectionName: { $regex: collectionName, $options: "i" },
name: { $regex: idFilter, $options: "i" },
},
undefined,
{ sort: parseSortString(sort), limit: perPage }
);
} else {
nfts = await NFT.find(
{
collectionName: { $regex: collectionName, $options: "i" },
},
undefined,
{
limit: perPage,
skip: page * perPage,
sort: parseSortString(sort),
}
);
}

if (nfts) {
res.status(200).json(JSON.stringify(nfts, undefined, 4));
if (collection) {
res.status(200).json(JSON.stringify(collection, undefined, 4));
return;
} else {
res.status(404).json({
error: true,
message: "Failed to find nfts with collectionName:",
message: "Failed to find collection with collectionName:",
collectionName,
});
return;
}
}

function parseSortString(sort: string) {
let isNegative = sort.substr(0, 1) === "-";

let ret: any = {};

if (isNegative) {
ret[sort.substr(1)] = -1;
} else {
ret[sort.substr(0)] = 1;
}

return ret;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next";
import dbConnect from "../../../../../libs/dbConnect/dbConnect";
import { NFT } from "../../../../../models/NFT";
import dbConnect from "../../../../../../libs/dbConnect/dbConnect";
import { NFT } from "../../../../../../models/NFT";

export default async function handler(
req: NextApiRequest,
Expand Down
Loading

1 comment on commit 32acbdb

@vercel
Copy link

@vercel vercel bot commented on 32acbdb Oct 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.