Skip to content

Commit

Permalink
Various design improvements + reviews
Browse files Browse the repository at this point in the history
  • Loading branch information
dcramer committed Dec 31, 2023
1 parent 189a661 commit 0eb7dc3
Show file tree
Hide file tree
Showing 33 changed files with 169 additions and 43 deletions.
5 changes: 5 additions & 0 deletions apps/server/src/bin/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ const loadDefaultBottles = async (
bottleId: bottle.id,
}));

await Fixtures.Review({
externalSiteId: site.id,
bottleId: bottle.id,
});

for (let i = 0; i < dates.length; i++) {
(await db.query.storePriceHistories.findFirst({
where: (storePriceHistories, { eq }) =>
Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/lib/test/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ export const Review = async ({ ...data }: Partial<NewReview> = {}) => {
.values({
name: "",
externalSiteId: data.externalSiteId || (await ExternalSite()).id,
rating: faker.number.int({ min: 30, max: 100 }),
rating: faker.number.int({ min: 59, max: 100 }),
url: faker.internet.url(),
issue: "Default",
...data,
Expand Down
66 changes: 63 additions & 3 deletions apps/server/src/serializers/review.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,73 @@
import { serializer } from ".";
import type { Review, User } from "../db/schema";
import { inArray } from "drizzle-orm";
import { serialize, serializer } from ".";
import { db } from "../db";
import {
bottles,
externalSites,
type Bottle,
type Review,
type User,
} from "../db/schema";
import { notEmpty } from "../lib/filter";
import { BottleSerializer } from "./bottle";
import { ExternalSiteSerializer } from "./externalSite";

type ReviewAttrs = {
bottle: ReturnType<(typeof BottleSerializer)["item"]> | null;
site: ReturnType<(typeof ExternalSiteSerializer)["item"]>;
};

export const ReviewSerializer = serializer({
item: (item: Review, attrs: Record<string, any>, currentUser?: User) => {
attrs: async (
itemList: (Review & { bottle: Bottle })[],
currentUser?: User,
): Promise<Record<string, ReviewAttrs>> => {
const bottleIds = Array.from(
new Set(itemList.map((i) => i.bottleId).filter(notEmpty)),
);
const bottleList = bottleIds.length
? await db.select().from(bottles).where(inArray(bottles.id, bottleIds))
: [];
const bottlesByRef = Object.fromEntries(
(await serialize(BottleSerializer, bottleList, currentUser)).map(
(data, index) => [bottleList[index].id, data],
),
);

const siteIds = Array.from(new Set(itemList.map((i) => i.externalSiteId)));
const siteList = siteIds.length
? await db
.select()
.from(externalSites)
.where(inArray(externalSites.id, siteIds))
: [];
const sitesByRef = Object.fromEntries(
(await serialize(ExternalSiteSerializer, siteList, currentUser)).map(
(data, index) => [siteList[index].id, data],
),
);

return Object.fromEntries(
itemList.map((item) => {
return [
item.id,
{
bottle: item.bottleId ? bottlesByRef[item.bottleId] : null,
site: sitesByRef[item.externalSiteId],
},
];
}),
);
},

item: (item: Review, attrs: ReviewAttrs, currentUser?: User) => {
return {
id: item.id,
name: item.name,
rating: item.rating,
url: item.url,
bottle: attrs.bottle,
site: attrs.site,
};
},
});
1 change: 1 addition & 0 deletions apps/server/src/trpc/routes/reviewList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export default publicProcedure
ReviewSerializer,
results.slice(0, limit),
ctx.user,
[...(input.site ? ["site"] : []), ...(input.bottle ? ["bottle"] : [])],
),
rel: {
nextCursor: results.length > limit ? cursor + 1 : null,
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/components/admin/badgeTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default ({
<col className="min-w-full sm:w-1/2" />
<col className="sm:w-1/2" />
</colgroup>
<thead className="hidden border-b border-slate-800 text-sm font-semibold text-slate-500 sm:table-header-group">
<thead className="text-light hidden border-b border-slate-800 text-sm font-semibold sm:table-header-group">
<tr>
<th scope="col" className="px-3 py-2.5 text-left">
Badge
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/components/admin/reviewTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default ({
<col className="min-w-full sm:w-1/2" />
<col className="sm:w-1/2" />
</colgroup>
<thead className="hidden border-b border-slate-800 text-sm font-semibold text-slate-500 sm:table-header-group">
<thead className="text-light hidden border-b border-slate-800 text-sm font-semibold sm:table-header-group">
<tr>
<th scope="col" className="px-3 py-2.5 text-left">
Name
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/components/admin/siteTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default ({
<col className="min-w-full sm:w-1/2" />
<col className="sm:w-1/2" />
</colgroup>
<thead className="hidden border-b border-slate-800 text-sm font-semibold text-slate-500 sm:table-header-group">
<thead className="text-light hidden border-b border-slate-800 text-sm font-semibold sm:table-header-group">
<tr>
<th scope="col" className="px-3 py-2.5 text-left">
Site
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/components/admin/storePriceTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default ({
<col className="min-w-full sm:w-1/2" />
<col className="sm:w-1/2" />
</colgroup>
<thead className="hidden border-b border-slate-800 text-sm font-semibold text-slate-500 sm:table-header-group">
<thead className="text-light hidden border-b border-slate-800 text-sm font-semibold sm:table-header-group">
<tr>
<th scope="col" className="px-3 py-2.5 text-left">
Name
Expand Down
4 changes: 2 additions & 2 deletions apps/web/app/components/appFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import NotificationsPanel from "./notifications/panel";

export function AppFooter() {
return (
<nav className="sm:min-h-18 min-h-14 mx-auto flex w-full max-w-4xl items-center justify-center gap-x-6 px-3 sm:px-3 lg:px-0">
<nav className="sm:min-h-18 mx-auto flex min-h-14 w-full max-w-4xl items-center justify-center gap-x-6 px-3 sm:px-3 lg:px-0">
<NavLink to="/">
<GlobeAmericasIcon className="h-8 w-8 sm:h-9 sm:w-9" />
</NavLink>
Expand All @@ -16,7 +16,7 @@ export function AppFooter() {

<NavLink
to="/search?tasting"
className="focus:ring-highlight relative -mt-5 flex max-w-xs items-center rounded border-t border-t-slate-700 bg-slate-950 text-sm text-slate-500 hover:bg-slate-700 focus:outline-none focus:ring"
className="focus:ring-highlight text-light relative -mt-5 flex max-w-xs items-center rounded border-t border-t-slate-700 bg-slate-950 text-sm hover:bg-slate-700 focus:outline-none focus:ring"
>
<PeatedGlyph className="m-5 h-9 w-9" />
</NavLink>
Expand Down
4 changes: 2 additions & 2 deletions apps/web/app/components/bottleHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ export default function BottleHeader({
titleExtra={
<BottleMetadata
data={bottle}
className="w-full truncate text-center text-slate-500 lg:text-left"
className="text-light w-full truncate text-center lg:text-left"
/>
}
metadata={
(bottle.category || bottle.statedAge) && (
<div className="flex w-full min-w-[150px] flex-col items-center justify-center gap-x-1 text-slate-500 lg:w-auto lg:items-end">
<div className="text-light flex w-full min-w-[150px] flex-col items-center justify-center gap-x-1 lg:w-auto lg:items-end">
<div>
{bottle.category && (
<Link
Expand Down
19 changes: 19 additions & 0 deletions apps/web/app/components/bottleOverview.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Bottle } from "@peated/server/types";
import RobotImage from "@peated/web/assets/robot.png";
import { Fragment } from "react";
import BottleReviews from "./bottleReviews.client";
import BottleTagDistribution from "./bottleTagDistribution.client";
import { ClientOnly } from "./clientOnly";
import Markdown from "./markdown";
Expand Down Expand Up @@ -34,6 +35,24 @@ export default function BottleOverview({ bottle }: { bottle: Bottle }) {
</ClientOnly>
</div>

<div className="my-6 px-3 md:px-0">
<ClientOnly>
{() => (
<QueryBoundary
fallback={
<div
className="animate-pulse bg-slate-800"
style={{ height: 200 }}
/>
}
loading={<Fragment />}
>
<BottleReviews bottleId={bottle.id} />
</QueryBoundary>
)}
</ClientOnly>
</div>

{(bottle.description || bottle.tastingNotes) && (
<div className="my-6 px-3 md:px-0">
{bottle.description && (
Expand Down
44 changes: 44 additions & 0 deletions apps/web/app/components/bottleReviews.client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { TrophyIcon } from "@heroicons/react/24/outline";
import { trpc } from "../lib/trpc";

function RatingIcon({ rating }: { rating: number }) {
if (rating > 93) return <TrophyIcon className="text-highlight h-4 w-4" />;
if (rating > 87) return <TrophyIcon className="h-4 w-4 text-gray-400" />;
if (rating > 83) return <TrophyIcon className="h-4 w-4 text-orange-400" />;
return null;
}

export default function BottleReviews({ bottleId }: { bottleId: number }) {
const { data } = trpc.reviewList.useQuery({
bottle: bottleId,
});

if (!data) return null;

const { results } = data;

if (!results.length) return null;

return (
<>
<h3 className="text-highlight text-lg font-bold">The Critics</h3>
<ul className="-mx-2 grid w-2/3 grid-cols-2 md:w-1/2">
{results.map((r) => {
return (
<li
key={r.id}
className="relative col-span-3 grid grid-cols-subgrid items-center gap-x-2 gap-y-2 p-2 hover:bg-slate-800"
>
<a href={r.url} className="absolute inset-0" />
<span className="flex items-center gap-x-2">{r.site.name}</span>
<span className="flex items-center justify-end gap-x-2">
<RatingIcon rating={r.rating} />
<span>{r.rating} points</span>
</span>
</li>
);
})}
</ul>
</>
);
}
4 changes: 2 additions & 2 deletions apps/web/app/components/bottleTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default ({
<col className="sm:w-1/6" />
<col className="sm:w-1/6" />
</colgroup>
<thead className="hidden border-b border-slate-800 text-sm font-semibold text-slate-500 sm:table-header-group">
<thead className="text-light hidden border-b border-slate-800 text-sm font-semibold sm:table-header-group">
<tr>
<th scope="col" className="py-3.5 pl-4 pr-3 text-left sm:pl-3">
<SortParam name="name" label="Bottle" sort={sort} />
Expand Down Expand Up @@ -102,7 +102,7 @@ export default ({
<CheckBadgeIcon className="h-4 w-4" aria-hidden="true" />
)}
</div>
<div className="text-sm text-slate-500">
<div className="text-light text-sm">
<Link
to={`/bottles/?category=${bottle.category}`}
className="hover:underline"
Expand Down
6 changes: 2 additions & 4 deletions apps/web/app/components/breadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function Breadcrumbs({ pages }: { pages: Page[] }) {
<ol role="list" className="flex items-center space-x-2">
<li className="flex">
<div className="flex items-center">
<Link to="/" className="text-slate-500 hover:text-slate-400">
<Link to="/" className="text-light hover:text-slate-400">
<HomeIcon className="h-5 w-5 flex-shrink-0" aria-hidden="true" />
<span className="sr-only">Home</span>
</Link>
Expand All @@ -29,9 +29,7 @@ export function Breadcrumbs({ pages }: { pages: Page[] }) {
/>
<Link
to={page.to}
className={classNames(
"ml-2 text-slate-600 hover:text-slate-500",
)}
className={classNames("hover:text-light ml-2 text-slate-600")}
aria-current={page.current ? "page" : undefined}
>
{page.name}
Expand Down
3 changes: 1 addition & 2 deletions apps/web/app/components/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ export default forwardRef<null | HTMLButtonElement | typeof Link, Props>(
if (active) {
textColor = "text-highlight";
} else if (disabled) {
textColor =
color === "highlight" ? "text-highlight-dark" : "text-slate-500";
textColor = color === "highlight" ? "text-highlight-dark" : "text-light";
}

if (to) {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/components/chip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function Chip<E extends ElementType = typeof defaultElement>({
break;
case "default":
default:
colorClass = " border-slate-700 text-slate-500";
colorClass = " border-slate-700 text-light";
}

const moreProps = Component === defaultElement ? { layout: true } : {};
Expand Down
4 changes: 2 additions & 2 deletions apps/web/app/components/entityTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default ({
{withTastings && <col className="sm:w-1/10" />}
<col className="sm:w-3/10" />
</colgroup>
<thead className="hidden border-b border-slate-800 text-sm font-semibold text-slate-500 sm:table-header-group">
<thead className="text-light hidden border-b border-slate-800 text-sm font-semibold sm:table-header-group">
<tr>
<th scope="col" className="px-3 py-2.5 text-left">
<SortParam name="name" label="Entity" sort={sort} />
Expand Down Expand Up @@ -106,7 +106,7 @@ export default ({
to={`/entities?region=${encodeURIComponent(
entity.region,
)}`}
className="text-slate-500 hover:underline"
className="text-light hover:underline"
>
{entity.region}
</Link>
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/components/formLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function FormLabel<
}`}
>
<div>{children}</div>
<span className="text-xs leading-6 text-slate-500">
<span className="text-light text-xs leading-6">
{labelNote || (!required && "Optional")}
</span>
</Component>
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/components/navLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function NavLink(props: ComponentProps<typeof RRNavLink>) {
className={({ isActive, isPending }) =>
classNames(
baseClassNames,
isActive ? "text-highlight" : "text-slate-500 hover:text-white",
isActive ? "text-highlight" : "text-light hover:text-white",
)
}
{...props}
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/components/notifications/entry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default function NotificationEntry({
e.stopPropagation();
onArchive();
}}
className="block h-full w-full rounded bg-inherit p-2 px-1 text-slate-600 hover:bg-slate-800 hover:text-slate-400 group-hover:text-slate-500"
className="group-hover:text-light block h-full w-full rounded bg-inherit p-2 px-1 text-slate-600 hover:bg-slate-800 hover:text-slate-400"
>
<XMarkIcon className="h-6 w-6" />
</button>
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/components/pageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function PageHeader({
</div>

{!!metadata && (
<div className="flex w-full min-w-[150px] flex-col items-center justify-center gap-x-1 text-slate-500 lg:w-auto lg:items-end">
<div className="text-light flex w-full min-w-[150px] flex-col items-center justify-center gap-x-1 lg:w-auto lg:items-end">
{metadata}
</div>
)}
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/components/profileDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export function ProfileDropdown() {
"relative flex max-w-xs items-center p-2 text-sm hover:bg-slate-800 hover:text-white focus:outline-none",
open
? "rounded-b-none rounded-t bg-slate-800 text-white"
: "rounded text-slate-500",
: "text-light rounded",
)}
onClick={openMenu}
as={Link}
Expand Down
4 changes: 2 additions & 2 deletions apps/web/app/components/search/bottleResult.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ export default function BottleResultRow({
</div>
<div className="flex items-center gap-x-4">
<div className="hidden sm:flex sm:flex-col sm:items-end">
<div className="leading-6 text-slate-500">
<div className="text-light leading-6">
{bottle.category && formatCategoryName(bottle.category)}
</div>
<div className="mt-1 text-sm leading-5 text-slate-500">
<div className="text-light mt-1 text-sm leading-5">
{bottle.statedAge ? `${bottle.statedAge} years` : null}
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/components/selectField/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export default ({
</Chip>
))}
{visibleValues.length === 0 && placeholder && (
<div className="text-slate-500 sm:leading-6">{placeholder}</div>
<div className="text-light sm:leading-6">{placeholder}</div>
)}
{visibleValues.length > 0 &&
value.length < targetOptions &&
Expand Down
Loading

0 comments on commit 0eb7dc3

Please sign in to comment.