Skip to content

Commit

Permalink
feat: Enable quest editing directly from quest (#233)
Browse files Browse the repository at this point in the history
  • Loading branch information
evadecker authored Nov 28, 2024
1 parent 529e2df commit 6174fc5
Show file tree
Hide file tree
Showing 32 changed files with 1,456 additions and 267 deletions.
5 changes: 5 additions & 0 deletions .changeset/clean-jars-trade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"namesake": minor
---

Allow editing quest costs and time required directly from the quest page
22 changes: 22 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,28 @@ jobs:
- name: Biome Linter, Formatter, and Import Sorter
run: pnpm biome ci

test:
name: Unit Test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup PNPM
uses: pnpm/action-setup@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: "pnpm"

- name: Install dependencies
run: pnpm install

- name: Run tests
run: pnpm test

# Enable this once preview deploys are working and we can run on the preview directly
# e2e:
# name: End-to-end Test
Expand Down
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
"files": {
"ignore": ["convex/_generated", "routeTree.gen.ts", "dist"]
"ignore": ["convex/_generated", "routeTree.gen.ts", "dist", "node_modules"]
},
"formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2 },
"linter": {
Expand Down
36 changes: 36 additions & 0 deletions convex/quests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,42 @@ export const updateQuest = userMutation({
},
});

export const updateQuestCosts = userMutation({
args: {
questId: v.id("quests"),
costs: v.optional(
v.array(
v.object({
cost: v.number(),
description: v.string(),
}),
),
),
},
handler: async (ctx, args) => {
await ctx.db.patch(args.questId, { costs: args.costs });
},
});

export const updateQuestTimeRequired = userMutation({
args: {
questId: v.id("quests"),
timeRequired: v.optional(
v.object({
min: v.number(),
max: v.number(),
unit: timeRequiredUnit,
description: v.optional(v.string()),
}),
),
},
handler: async (ctx, args) => {
await ctx.db.patch(args.questId, {
timeRequired: args.timeRequired,
});
},
});

export const deleteQuest = userMutation({
args: { questId: v.id("quests") },
handler: async (ctx, args) => {
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
"@tailwindcss/typography": "^0.5.15",
"@tanstack/router-devtools": "^1.82.8",
"@tanstack/router-plugin": "^1.81.9",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.0.1",
"@testing-library/user-event": "^14.5.2",
"@types/node": "^22.9.3",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
Expand All @@ -100,6 +104,7 @@
"tailwindcss-react-aria-components": "^1.2.0",
"typescript": "^5.7.2",
"vite": "^5.4.11",
"vite-tsconfig-paths": "^5.1.3",
"vitest": "^2.1.5"
},
"packageManager": "[email protected]"
Expand Down
92 changes: 92 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/components/common/Dialog/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function Dialog(props: DialogProps) {
<AriaDialog
{...props}
className={twMerge(
"outline outline-0 p-6 [[data-placement]>&]:p-4 max-h-[inherit] overflow-auto relative",
"outline outline-0 p-0 max-h-[inherit] relative",
props.className,
)}
/>
Expand Down
8 changes: 4 additions & 4 deletions src/components/common/Field/Field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ export function FieldError(props: FieldErrorProps) {
export const fieldBorderStyles = tv({
variants: {
isFocusWithin: {
false: "border-gray-dim forced-colors:border-[ButtonBorder]",
true: "border-gray-normal forced-colors:border-[Highlight]",
false: "border-black/10 dark:border-white/10",
true: "border-black/15 dark:border-white/15",
},
isInvalid: {
true: "border-red-normal bg-red-subtle forced-colors:border-[Mark]",
Expand All @@ -68,7 +68,7 @@ export const fieldBorderStyles = tv({

export const fieldGroupStyles = tv({
extend: focusRing,
base: "group flex items-center bg-gray-subtle forced-colors:bg-[Field] border rounded-lg overflow-hidden",
base: "group h-10 flex items-center bg-gray-subtle forced-colors:bg-[Field] border rounded-lg overflow-hidden",
variants: fieldBorderStyles.variants,
});

Expand All @@ -84,7 +84,7 @@ export function FieldGroup(props: GroupProps) {
}

export const inputStyles =
"px-3 py-2 flex-1 min-w-0 outline outline-0 bg-transparent text-gray-normal disabled:text-gray-dim";
"px-3 h-10 flex-1 min-w-0 outline outline-0 bg-transparent text-gray-normal disabled:text-gray-dim";

export function Input(props: InputProps) {
return (
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/Form/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export function Form(props: FormProps) {
return (
<AriaForm
{...props}
className={twMerge("flex flex-col gap-6", props.className)}
className={twMerge("flex flex-col gap-6 items-start", props.className)}
/>
);
}
26 changes: 24 additions & 2 deletions src/components/common/Modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {
Modal as AriaModal,
Heading,
ModalOverlay,
type ModalOverlayProps,
} from "react-aria-components";
import { tv } from "tailwind-variants";
import { Dialog } from "../Dialog";

const overlayStyles = tv({
base: "fixed top-0 left-0 w-full h-[--visual-viewport-height] isolate z-20 bg-black/[15%] flex items-center justify-center p-4 backdrop-blur-lg",
Expand All @@ -18,7 +20,7 @@ const overlayStyles = tv({
});

const modalStyles = tv({
base: "p-4 w-full max-w-md max-h-full rounded-2xl bg-gray-subtle forced-colors:bg-[Canvas] flex flex-col items-start gap-4 shadow-2xl bg-clip-padding border border-gray-dim",
base: "p-5 w-full max-w-md max-h-full rounded-2xl bg-gray-subtle forced-colors:bg-[Canvas] flex flex-col items-start gap-4 shadow-2xl bg-clip-padding border border-gray-dim",
variants: {
isEntering: {
true: "animate-in zoom-in-105 ease-out duration-2",
Expand All @@ -32,7 +34,27 @@ const modalStyles = tv({
export function Modal(props: ModalOverlayProps) {
return (
<ModalOverlay {...props} className={overlayStyles}>
<AriaModal {...props} className={modalStyles} />
<Dialog>
<AriaModal {...props} className={modalStyles}>
{props.children}
</AriaModal>
</Dialog>
</ModalOverlay>
);
}

type ModalHeaderProps = {
title: string;
children?: React.ReactNode;
};

export function ModalHeader({ title, children }: ModalHeaderProps) {
return (
<header className="flex items-center justify-between w-full">
<Heading className="text-xl font-medium text-gray-normal" slot="title">
{title}
</Heading>
{children}
</header>
);
}
2 changes: 1 addition & 1 deletion src/components/common/NumberField/NumberField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function NumberField({
"group flex flex-col gap-1.5",
)}
>
<Label>{label}</Label>
{label && <Label>{label}</Label>}
<FieldGroup>
{(renderProps) => (
<>
Expand Down
3 changes: 2 additions & 1 deletion src/components/common/Popover/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
useSlottedContext,
} from "react-aria-components";
import { tv } from "tailwind-variants";
import { Dialog } from "../Dialog";

export interface PopoverProps extends Omit<AriaPopoverProps, "children"> {
children: React.ReactNode;
Expand Down Expand Up @@ -37,7 +38,7 @@ export function Popover({ children, className, ...props }: PopoverProps) {
styles({ ...renderProps, className }),
)}
>
{children}
<Dialog>{children}</Dialog>
</AriaPopover>
);
}
Loading

0 comments on commit 6174fc5

Please sign in to comment.