Skip to content

Commit

Permalink
feat: lot of optimize (#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
PaiJi authored May 7, 2024
1 parent 7a5c38d commit 8f441f2
Show file tree
Hide file tree
Showing 8 changed files with 666 additions and 226 deletions.
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
"clean": "rm -rf .next && rm -rf out"
},
"dependencies": {
"@headlessui/react": "^1.7.19",
"@sentry/nextjs": "^7.112.2",
"@headlessui/react": "^2.0.1",
"@radix-ui/react-collapsible": "^1.0.3",
"@sentry/nextjs": "^7.113.0",
"@xata.io/client": "^0.29.4",
"autoprefixer": "^10.4.19",
"clsx": "^2.1.1",
"date-fns": "^3.6.0",
"embla-carousel-autoplay": "^8.0.2",
"embla-carousel-react": "^8.0.2",
"embla-carousel-autoplay": "^8.0.4",
"embla-carousel-react": "^8.0.4",
"eslint": "8.57.0",
"eslint-config-next": "14.2.3",
"git-revision-webpack-plugin": "^5.0.0",
Expand All @@ -33,7 +34,7 @@
"react": "18.3.1",
"react-dom": "18.3.1",
"react-hot-toast": "^2.4.1",
"react-icons": "^5.2.0",
"react-icons": "^5.2.1",
"superjson": "1.13.3",
"tailwindcss": "^3.4.3",
"typescript": "5.4.5"
Expand Down
4 changes: 2 additions & 2 deletions src/components/layout/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export default function Header() {
<div className="flex">
<h1 className="text-base mt-0">FEC·兽展日历</h1>
<span className="text-base mx-1">/</span>
<span className="text-base">五一五一🥳</span>
{/* <span className="text-base">等待假期🌔</span> */}
{/* <span className="text-base">五一五一🥳</span> */}
<span className="text-base">等待假期🌔</span>
</div>
</div>
</Link>
Expand Down
9 changes: 9 additions & 0 deletions src/components/ui/collapsible/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";

const Collapsible = CollapsiblePrimitive.Root;

const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;

const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;

export { Collapsible, CollapsibleTrigger, CollapsibleContent };
30 changes: 27 additions & 3 deletions src/pages/[organization]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import toast from "react-hot-toast";
import { FaPaw, FaQq, FaTwitter, FaWeibo } from "react-icons/fa";
import { MdOutlineContentCopy } from "react-icons/md";
import { SiBilibili } from "react-icons/si";
import { formatDistanceToNowStrict } from "date-fns";
import { zhCN } from "date-fns/locale";
// import {
// WebsiteButton,
// QQGroupButton,
Expand All @@ -27,6 +29,21 @@ export default function OrganizationDetail(props: {
}) {
const { organization, events } = props;

const foramtedFirstEventTime = useMemo(() => {
const theBeginningEvent = events[events.length - 1];
if (theBeginningEvent.startDate) {
const date = new Date(theBeginningEvent.startDate);

return {
year: date.getUTCFullYear(),
month: date.getUTCMonth() + 1,
day: date.getUTCDate(),
};
}

return null;
}, [events]);

const formatedCreationTime = useMemo(() => {
if (organization.creationTime) {
const date = new Date(organization.creationTime);
Expand All @@ -35,6 +52,7 @@ export default function OrganizationDetail(props: {
year: date.getUTCFullYear(),
month: date.getUTCMonth() + 1,
day: date.getUTCDate(),
createDistance: formatDistanceToNowStrict(date, { locale: zhCN }),
};
} else {
return null;
Expand Down Expand Up @@ -65,12 +83,18 @@ export default function OrganizationDetail(props: {
</div>

<div className={clsx("mb-2 text-gray-500", styles["intro-bar"])}>
<span>已累计举办 {events.length} 场展会</span>
{formatedCreationTime && (
<span className="lex items-center">
{`首次举办于 ${formatedCreationTime?.year}${formatedCreationTime?.month}${formatedCreationTime?.day}日`}
<span>已创立 {formatedCreationTime.createDistance}</span>
)}
<span>已累计收录 {events.length} 场展会</span>
{foramtedFirstEventTime && (
<span>
{`首次举办于 ${foramtedFirstEventTime?.year}${foramtedFirstEventTime?.month}${foramtedFirstEventTime?.day}日`}
</span>
)}
{formatedCreationTime && (
<span>{`首次出现于 ${formatedCreationTime?.year}${formatedCreationTime?.month}${formatedCreationTime?.day}日`}</span>
)}
</div>

<div
Expand Down
155 changes: 104 additions & 51 deletions src/pages/city.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import { sortByStartDateDesc } from "@/utils/event";
import { eventGroupByYear } from "@/utils/event";
import { sendTrack } from "@/utils/track";
import { Event, XataClient } from "@/xata/xata";
import groupBy from "lodash-es/groupBy";
import Link from "next/link";
import { useMemo } from "react";
import { useMemo, useState } from "react";
import { getEventCoverUrl } from "@/utils/imageLoader";
import { format } from "date-fns";
import Image from "@/components/image";
import { titleGenerator } from "@/utils/meta";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
import { Button } from "@headlessui/react";
import { FaAngleDown, FaLink } from "react-icons/fa6";

export default function City(props: { events: Event[] }) {
const { events } = props;
Expand All @@ -20,7 +30,7 @@ export default function City(props: { events: Event[] }) {
const groupByCityAndYearEvents = useMemo(() => {
const output = cities.map((c) => ({
location: c,
eventsGroup: sortByStartDateDesc(groupByCityEvents[c]),
eventsGroup: eventGroupByYear(groupByCityEvents[c], "desc"),
}));
return output;
}, [cities, groupByCityEvents]);
Expand All @@ -38,7 +48,7 @@ export default function City(props: { events: Event[] }) {
return (
<>
<div className="bg-white border p-6 rounded-xl">
<ul className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4">
<ul className="grid grid-cols-3 sm:grid-cols-3 md:grid-cols-4 gap-4">
{cities.map((city) => (
<li key={city} className="group">
<a
Expand All @@ -53,7 +63,8 @@ export default function City(props: { events: Event[] }) {
})
}
>
<h2 className="text-lg font-bold text-gray-600 group-hover:text-red-400 transition duration-300">
<h2 className="text-lg font-bold text-gray-600 flex items-center group-hover:text-red-400 transition duration-300">
<FaLink className="inline-block h-3 w-3 mr-1" />
{city}
<span className="text-sm font-normal ml-1">
{groupByCityEvents[city].length}
Expand Down Expand Up @@ -93,49 +104,11 @@ export default function City(props: { events: Event[] }) {
<h3 className="text-gray-500">
{yearGroup.year === "no-date" ? "暂未定档" : yearGroup.year}
</h3>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4 mt-4">
{yearGroup.events.map((event) => (
<Link
key={event.id}
href={`/${event.organization?.slug}/${event.slug}`}
onClick={() =>
sendTrack({
eventName: "click-mini-event-card",
eventValue: {
href: `/${event.organization?.slug}/${event.slug}`,
from: "city list",
},
})
}
className="rounded-xl shadow-xl h-36 relative flex justify-center items-center group"
>
{/* <div className="w-full h-36 overflow-hidden rounded-t-xl p-4">
{event.coverUrl?.[0] && (
<Image
alt="event cover"
src={event.coverUrl?.[0]}
width={40}
height={40}
className="h-full w-full object-cover rounded-xl overflow-hidden"
/>
)}
</div> */}
<div
className="rounded-xl duration-500 transition group-hover:border-gray-400 w-full h-full absolute brightness-75 hover:brightness-100"
style={{
backgroundImage: `url(${getEventCoverUrl(event)})`,
backgroundPosition: "center",
backgroundRepeat: "no-repeat",
backgroundSize: "cover",
// filter: "brightness(0.9)",
}}
></div>
<div className="z-10 relative pointer-events-none">
<span className="tracking-wide text-white font-bold text-lg text-center inline-block w-full">{`${event.organization?.name} · ${event.name}`}</span>
</div>
</Link>
))}
</div>
<CityYearSelection events={yearGroup.events} />
{/* <CollapsibleCityYearSelection
year={yearGroup.year}
events={yearGroup.events}
/> */}
</div>
))}
</div>
Expand All @@ -146,6 +119,85 @@ export default function City(props: { events: Event[] }) {
);
}

function CityYearSelection({ events }: { events: Event[] }) {
return (
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4 mt-4">
{events.map((event) => (
<Link
key={event.id}
href={`/${event.organization?.slug}/${event.slug}`}
onClick={() =>
sendTrack({
eventName: "click-mini-event-card",
eventValue: {
href: `/${event.organization?.slug}/${event.slug}`,
from: "city list",
},
})
}
className="rounded-xl shadow-xl h-36 relative flex justify-center items-center group"
>
<div className="rounded-xl duration-500 transition group-hover:border-gray-400 w-full h-full absolute brightness-75 hover:brightness-100">
<Image
alt="活动背景"
src={getEventCoverUrl(event)}
width={350}
className="h-full w-full object-cover rounded-xl overflow-hidden"
autoFormat
/>
</div>
<div className="z-10 relative pointer-events-none">
<h4 className="tracking-wide text-white font-bold text-lg text-center">{`${event.organization?.name} · ${event.name}`}</h4>
{event.startDate && event.endDate && (
<p className="text-center text-white">
{event.startDate && (
<span>{format(event.startDate, "MM月dd日")}</span>
)}
-
{event.startDate && (
<span>{format(event.startDate, "MM月dd日")}</span>
)}
</p>
)}
</div>
</Link>
))}
</div>
);
}

function CollapsibleCityYearSelection({
events,
year,
}: {
events: Event[];
year: string;
}) {
const [isOpen, setIsOpen] = useState(false);

return (
<Collapsible open={isOpen} onOpenChange={setIsOpen}>
<div className="flex items-center justify-between space-x-4 px-4">
<CollapsibleTrigger asChild>
<div className="flex cursor-pointer">
<h3 className="text-gray-500">
{year === "no-date" ? "暂未定档" : year}
</h3>
<Button>
<FaAngleDown className="h-4 w-4" />
<span className="sr-only">Toggle</span>
</Button>
</div>
</CollapsibleTrigger>
</div>

<CollapsibleContent className="space-y-2">
<CityYearSelection events={events} />
</CollapsibleContent>
</Collapsible>
);
}

export async function getStaticProps() {
const xata = new XataClient();

Expand All @@ -157,6 +209,7 @@ export async function getStaticProps() {
"posterUrl",
"coverUrl",
"startDate",
"endDate",
"organization.slug",
"organization.name",
])
Expand All @@ -167,9 +220,9 @@ export async function getStaticProps() {
props: {
events,
headMetas: {
title: "兽展城市列表",
des: `欢迎来到FEC·兽展日历!FEC·兽展日历共收录来自中国大陆共 ${cities} 个城市举办过的 ${events.length}Furry 相关的展会活动信息!快来看看这些城市有没有你所在的地方吧!`,
link: "https://www.furryeventchina.com/city",
title: titleGenerator("兽展城市列表"),
des: `欢迎来到FEC·兽展日历!FEC·兽展日历共收录来自中国大陆共 ${cities} 个城市举办过的 ${events.length}兽展(兽聚)活动信息!快来看看这些城市有没有你所在的地方吧!`,
link: "https://www.furryeventchina.com/city/",
},
structuredData: {
breadcrumb: {
Expand Down
26 changes: 12 additions & 14 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import { EventScale, EventStatus } from "@/types/event";
import { Switch } from "@headlessui/react";
import { sendTrack } from "@/utils/track";
import { DurationType } from "@/types/list";
import { filteringEvents, groupByCustomDurationEvent } from "@/utils/event";
import {
filteringEvents,
groupByCustomDurationEvent,
sortEvents,
} from "@/utils/event";

import { compareAsc } from "date-fns";

Expand Down Expand Up @@ -101,19 +105,13 @@ function DurationSection({
</span>
</h3>
<div className="grid gap-4 md:gap-12 grid-cols-1 xs:grid-cols-2 lg:grid-cols-3">
{groupByDateEvent[month]
.sort((a, b) =>
a.startDate && b.startDate
? compareAsc(a?.startDate, b.startDate)
: 0
)
.map((event) => (
<EventCard
key={event.name}
event={event}
sizes="(max-width: 750px) 650px, (max-width: 1080px) 552px, 552px"
/>
))}
{sortEvents(groupByDateEvent[month], "asc").map((event) => (
<EventCard
key={event.name}
event={event}
sizes="(max-width: 750px) 650px, (max-width: 1080px) 552px, 552px"
/>
))}
</div>
</div>
))}
Expand Down
Loading

0 comments on commit 8f441f2

Please sign in to comment.