Skip to content

Commit

Permalink
chore: Reorganize quest subcomponents (#232)
Browse files Browse the repository at this point in the history
  • Loading branch information
evadecker authored Nov 28, 2024
1 parent 199c48d commit 529e2df
Show file tree
Hide file tree
Showing 12 changed files with 197 additions and 160 deletions.
51 changes: 51 additions & 0 deletions src/components/quests/QuestCosts/QuestCosts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { StatGroup, StatPopover } from "@/components/quests";
import type { Cost } from "@convex/constants";
import { Fragment } from "react/jsx-runtime";

type QuestCostsProps = {
costs?: Cost[];
};

export const QuestCosts = ({ costs }: QuestCostsProps) => {
const getTotalCosts = (costs?: Cost[]) => {
if (!costs) return "Free";

const total = costs.reduce((acc, cost) => acc + cost.cost, 0);
return total > 0
? total.toLocaleString("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
})
: "Free";
};

return (
<StatGroup label="Cost" value={getTotalCosts(costs)}>
{costs?.length && (
<StatPopover tooltip="See cost breakdown">
<dl className="grid grid-cols-[1fr_auto]">
{costs.map(({ cost, description }) => (
<Fragment key={description}>
<dt className="text-gray-dim pr-4">{description}</dt>
<dd className="text-right">
{cost.toLocaleString("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
})}
</dd>
</Fragment>
))}
<dt className="text-gray-dim pr-4 border-t border-gray-dim pt-2 mt-2">
Total
</dt>
<dd className="text-right border-t border-gray-dim pt-2 mt-2">
{getTotalCosts(costs)}
</dd>
</dl>
</StatPopover>
)}
</StatGroup>
);
};
1 change: 1 addition & 0 deletions src/components/quests/QuestCosts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./QuestCosts";
38 changes: 38 additions & 0 deletions src/components/quests/QuestForms/QuestForms.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Badge } from "@/components/common";
import { api } from "@convex/_generated/api";
import type { Id } from "@convex/_generated/dataModel";
import { useQuery } from "convex/react";
import { DocumentCard } from "../DocumentCard";

type QuestFormsProps = {
questId: Id<"quests">;
};

export const QuestForms = ({ questId }: QuestFormsProps) => {
const forms = useQuery(api.forms.getFormsForQuest, {
questId,
});

if (!forms || forms.length === 0) return null;

return (
<div className="p-4 rounded-lg border border-gray-dim mb-8">
<header className="flex gap-1 items-center pb-4">
<h3 className="text-gray-dim text-sm">Forms</h3>
<Badge size="xs" className="rounded-full">
{forms.length}
</Badge>
</header>
<div className="flex gap-4 overflow-x-auto p-4 -m-4">
{forms.map((form) => (
<DocumentCard
key={form._id}
title={form.title}
formCode={form.formCode}
downloadUrl={form.url ?? undefined}
/>
))}
</div>
</div>
);
};
1 change: 1 addition & 0 deletions src/components/quests/QuestForms/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./QuestForms";
26 changes: 26 additions & 0 deletions src/components/quests/QuestTimeRequired/QuestTimeRequired.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { StatGroup, StatPopover } from "@/components/quests";
import type { TimeRequired } from "@convex/constants";

type QuestTimeRequiredProps = {
timeRequired: TimeRequired;
};

export const QuestTimeRequired = ({ timeRequired }: QuestTimeRequiredProps) => {
const getFormattedTime = (timeRequired: TimeRequired) => {
return timeRequired
? `${timeRequired.min}${timeRequired.max} ${timeRequired.unit}`
: "Unknown";
};

const formattedTime = getFormattedTime(timeRequired);

return (
<StatGroup label="Time" value={formattedTime}>
{timeRequired.description && (
<StatPopover tooltip="See details">
<p className="text-sm max-w-xs">{timeRequired.description}</p>
</StatPopover>
)}
</StatGroup>
);
};
1 change: 1 addition & 0 deletions src/components/quests/QuestTimeRequired/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./QuestTimeRequired";
21 changes: 21 additions & 0 deletions src/components/quests/QuestUrls/QuestUrls.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Link } from "@/components/common";
import { Link as LinkIcon } from "lucide-react";

type QuestUrlsProps = {
urls?: string[];
};

export const QuestUrls = ({ urls }: QuestUrlsProps) => {
if (!urls || urls.length === 0) return null;

return (
<div className="flex flex-col items-start gap-1 mb-4">
{urls.map((url) => (
<Link key={url} href={url} className="inline-flex gap-1 items-center">
<LinkIcon size={20} />
{url}
</Link>
))}
</div>
);
};
1 change: 1 addition & 0 deletions src/components/quests/QuestUrls/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./QuestUrls";
41 changes: 41 additions & 0 deletions src/components/quests/StatGroup/StatGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {
Button,
DialogTrigger,
Popover,
Tooltip,
TooltipTrigger,
} from "@/components/common";
import { CircleHelp } from "lucide-react";

export type StatPopoverProps = {
tooltip: string;
children: React.ReactNode;
};

export const StatPopover = ({ tooltip, children }: StatPopoverProps) => (
<DialogTrigger>
<TooltipTrigger>
<Button variant="icon" size="small">
<CircleHelp />
</Button>
<Tooltip>{tooltip}</Tooltip>
</TooltipTrigger>
<Popover className="p-4">{children}</Popover>
</DialogTrigger>
);

export type StatGroupProps = {
label: string;
value: string;
children?: React.ReactNode;
};

export const StatGroup = ({ label, value, children }: StatGroupProps) => (
<div className="flex flex-col flex-1 border border-gray-dim py-3 px-4 rounded-lg">
<div className="text-gray-dim text-sm">{label}</div>
<div className="text-xl flex gap-0.5 items-center">
{value}
{children}
</div>
</div>
);
1 change: 1 addition & 0 deletions src/components/quests/StatGroup/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./StatGroup";
5 changes: 5 additions & 0 deletions src/components/quests/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
export * from "./DocumentCard";
export * from "./QuestCosts";
export * from "./QuestForms";
export * from "./QuestTimeRequired";
export * from "./QuestUrls";
export * from "./ReadingScore";
export * from "./StatGroup";
export * from "./StatusSelect";
Loading

0 comments on commit 529e2df

Please sign in to comment.