Skip to content

Commit

Permalink
Remove fields, rename forms to documents
Browse files Browse the repository at this point in the history
  • Loading branch information
evadecker committed Dec 7, 2024
1 parent f0e6afe commit 9b0e814
Show file tree
Hide file tree
Showing 21 changed files with 307 additions and 509 deletions.
6 changes: 2 additions & 4 deletions convex/_generated/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ import type {
} from "convex/server";
import type * as auth from "../auth.js";
import type * as constants from "../constants.js";
import type * as forms from "../forms.js";
import type * as documents from "../documents.js";
import type * as helpers from "../helpers.js";
import type * as http from "../http.js";
import type * as passwordReset from "../passwordReset.js";
import type * as questFields from "../questFields.js";
import type * as questions from "../questions.js";
import type * as quests from "../quests.js";
import type * as seed from "../seed.js";
Expand All @@ -41,11 +40,10 @@ import type * as validators from "../validators.js";
declare const fullApi: ApiFromModules<{
auth: typeof auth;
constants: typeof constants;
forms: typeof forms;
documents: typeof documents;
helpers: typeof helpers;
http: typeof http;
passwordReset: typeof passwordReset;
questFields: typeof questFields;
questions: typeof questions;
quests: typeof quests;
seed: typeof seed;
Expand Down
52 changes: 0 additions & 52 deletions convex/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
AtSign,
Calendar,
CalendarClock,
CalendarDays,
Expand All @@ -13,26 +12,20 @@ import {
Computer,
Gamepad2,
GraduationCap,
Hash,
HeartPulse,
History,
House,
Landmark,
LaptopMinimal,
LetterText,
ListChecks,
LoaderCircle,
type LucideIcon,
Mail,
MapPin,
MessageCircle,
Milestone,
Moon,
Phone,
RectangleEllipsis,
Scale,
ShoppingBag,
SquareCheck,
Sun,
Zap,
} from "lucide-react";
Expand Down Expand Up @@ -101,51 +94,6 @@ interface FieldDetails {
icon: LucideIcon;
}

export type Field =
| "text"
| "textarea"
| "date"
| "select"
| "checkbox"
| "number"
| "email"
| "phone";

export const FIELDS: Record<string, FieldDetails> = {
text: {
label: "Text",
icon: RectangleEllipsis,
},
textarea: {
label: "Textarea",
icon: LetterText,
},
date: {
label: "Date",
icon: Calendar,
},
select: {
label: "Select",
icon: ListChecks,
},
checkbox: {
label: "Checkbox",
icon: SquareCheck,
},
number: {
label: "Number",
icon: Hash,
},
email: {
label: "Email",
icon: AtSign,
},
phone: {
label: "Phone",
icon: Phone,
},
} as const;

export type Theme = "system" | "light" | "dark";
export const THEMES: Record<Theme, FieldDetails> = {
system: {
Expand Down
52 changes: 26 additions & 26 deletions convex/forms.ts → convex/documents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,33 @@ import { jurisdiction } from "./validators";
export const getAll = query({
args: {},
handler: async (ctx) => {
return await ctx.db.query("forms").collect();
return await ctx.db.query("documents").collect();
},
});

export const getById = query({
args: { formId: v.id("forms") },
args: { documentId: v.id("documents") },
handler: async (ctx, args) => {
return await ctx.db.get(args.formId);
return await ctx.db.get(args.documentId);
},
});

export const getAllActive = query({
args: {},
handler: async (ctx) => {
return await ctx.db
.query("forms")
.query("documents")
.filter((q) => q.eq(q.field("deletionTime"), undefined))
.collect();
},
});

export const getURL = query({
args: { formId: v.id("forms") },
args: { documentId: v.id("documents") },
handler: async (ctx, args) => {
const form = await ctx.db.get(args.formId);
if (!form || !form.file) return null;
return await ctx.storage.getUrl(form.file);
const document = await ctx.db.get(args.documentId);
if (!document || !document.file) return null;
return await ctx.storage.getUrl(document.file);
},
});

Expand All @@ -52,9 +52,9 @@ export const generateUploadUrl = mutation(async (ctx) => {
});

export const upload = userMutation({
args: { formId: v.id("forms"), storageId: v.id("_storage") },
args: { documentId: v.id("documents"), storageId: v.id("_storage") },
handler: async (ctx, args) => {
return await ctx.db.patch(args.formId, {
return await ctx.db.patch(args.documentId, {
file: args.storageId,
});
},
Expand All @@ -63,16 +63,16 @@ export const upload = userMutation({
export const getByQuestId = query({
args: { questId: v.id("quests") },
handler: async (ctx, args) => {
const forms = await ctx.db
.query("forms")
const documents = await ctx.db
.query("documents")
.withIndex("quest", (q) => q.eq("questId", args.questId))
.filter((q) => q.eq(q.field("deletionTime"), undefined))
.collect();

return await Promise.all(
forms.map(async (form) => ({
...form,
url: form.file ? await ctx.storage.getUrl(form.file) : null,
documents.map(async (document) => ({
...document,
url: document.file ? await ctx.storage.getUrl(document.file) : null,
})),
);
},
Expand All @@ -81,15 +81,15 @@ export const getByQuestId = query({
export const create = userMutation({
args: {
title: v.string(),
formCode: v.optional(v.string()),
code: v.optional(v.string()),
jurisdiction: jurisdiction,
file: v.optional(v.id("_storage")),
questId: v.id("quests"),
},
handler: async (ctx, args) => {
return await ctx.db.insert("forms", {
return await ctx.db.insert("documents", {
title: args.title,
formCode: args.formCode,
code: args.code,
jurisdiction: args.jurisdiction,
file: args.file,
questId: args.questId,
Expand All @@ -99,25 +99,25 @@ export const create = userMutation({
});

export const softDelete = userMutation({
args: { formId: v.id("forms") },
args: { documentId: v.id("documents") },
handler: async (ctx, args) => {
await ctx.db.patch(args.formId, { deletionTime: Date.now() });
await ctx.db.patch(args.documentId, { deletionTime: Date.now() });
},
});

export const undoSoftDelete = userMutation({
args: { formId: v.id("forms") },
args: { documentId: v.id("documents") },
handler: async (ctx, args) => {
await ctx.db.patch(args.formId, { deletionTime: undefined });
await ctx.db.patch(args.documentId, { deletionTime: undefined });
},
});

export const deleteForever = userMutation({
args: { formId: v.id("forms") },
args: { documentId: v.id("documents") },
handler: async (ctx, args) => {
// TODO: Delete form references in other tables
// TODO: Delete document references in other tables

// Delete the form
await ctx.db.delete(args.formId);
// Delete the document
await ctx.db.delete(args.documentId);
},
});
41 changes: 0 additions & 41 deletions convex/questFields.ts

This file was deleted.

40 changes: 11 additions & 29 deletions convex/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
import {
category,
field,
groupQuestsBy,
jurisdiction,
role,
Expand Down Expand Up @@ -84,38 +83,22 @@ const quests = defineTable({
}).index("category", ["category"]);

/**
* A single input field which may be shared across multiple quests.
* A PDF document that can be filled out by users.
*/
const questFields = defineTable({
/** The type of field. (e.g. "text", "select") */
type: field,
/** The label for the field. (e.g. "First Name") */
label: v.string(),
/** A unique identifier for the field, camel cased. (e.g. "firstName") */
slug: v.string(),
/** Additional help text for the field. */
helpText: v.optional(v.string()),
/** Time in ms since epoch when the field was deleted. */
deletionTime: v.optional(v.number()),
});

/**
* A PDF form that can be filled out by users.
*/
const forms = defineTable({
/** The quest this form belongs to. */
const documents = defineTable({
/** The quest this document belongs to. */
questId: v.id("quests"),
/** The title of the form. (e.g. "Petition to Change Name of Adult") */
/** The title of the document. (e.g. "Petition to Change Name of Adult") */
title: v.string(),
/** The legal code for the form. (e.g. "CJP 27") */
formCode: v.optional(v.string()),
/** The user who created the form. */
/** The legal code for the document. (e.g. "CJP 27") */
code: v.optional(v.string()),
/** The user who created the document. */
creationUser: v.id("users"),
/** The storageId for the PDF file. */
file: v.optional(v.id("_storage")),
/** The US State the form applies to. */
/** The US State the document applies to. */
jurisdiction: jurisdiction,
/** Time in ms since epoch when the form was deleted. */
/** Time in ms since epoch when the document was deleted. */
deletionTime: v.optional(v.number()),
}).index("quest", ["questId"]);

Expand Down Expand Up @@ -152,7 +135,7 @@ const users = defineTable({
*/
const userEncryptedData = defineTable({
userId: v.id("users"),
fieldId: v.id("questFields"),
fieldId: v.string(),
value: v.string(),
}).index("userId", ["userId"]);

Expand Down Expand Up @@ -188,9 +171,8 @@ export default defineSchema({
...authTables,
questions,
topics,
forms,
documents,
quests,
questFields,
users,
userEncryptedData,
userSettings,
Expand Down
5 changes: 0 additions & 5 deletions convex/validators.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { v } from "convex/values";
import {
CATEGORIES,
FIELDS,
GROUP_QUESTS_BY,
JURISDICTIONS,
ROLES,
Expand All @@ -26,10 +25,6 @@ export const role = v.union(
...Object.keys(ROLES).map((role) => v.literal(role)),
);

export const field = v.union(
...Object.keys(FIELDS).map((field) => v.literal(field)),
);

export const groupQuestsBy = v.union(
...Object.keys(GROUP_QUESTS_BY).map((groupQuestsBy) =>
v.literal(groupQuestsBy),
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@
"resend": "4.0.1",
"sonner": "^1.7.0",
"storybook": "^8.4.6",
"survey-core": "^1.12.13",
"survey-creator-core": "^1.12.13",
"survey-creator-react": "^1.12.13",
"survey-react-ui": "^1.12.13",
"tailwind-variants": "^0.3.0",
"tailwindcss": "^3.4.15",
"tailwindcss-animate": "^1.0.7",
Expand Down
Loading

0 comments on commit 9b0e814

Please sign in to comment.