From 1b29784e6f3d90229e70879f904ef42cff884679 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 10 Jan 2026 18:54:07 +0000
Subject: [PATCH 1/4] Initial plan
From 5ce18566922ba60a99cb4e1d8eace215e4e75297 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 10 Jan 2026 19:02:44 +0000
Subject: [PATCH 2/4] Implement orders pages with filters and actions
Co-authored-by: ArcaEge <40526225+ArcaEge@users.noreply.github.com>
---
drizzle/0025_greedy_krista_starr.sql | 2 +
drizzle/meta/0025_snapshot.json | 1248 +++++++++++++++++
drizzle/meta/_journal.json | 7 +
package-lock.json | 28 +-
src/lib/server/db/schema.ts | 1 +
.../admin/admin/orders/+page.server.ts | 172 ++-
.../dashboard/admin/admin/orders/+page.svelte | 148 +-
.../admin/admin/orders/[id]/+page.server.ts | 500 +++----
.../admin/admin/orders/[id]/+page.svelte | 321 +++--
.../market/item/[id]/+page.server.ts | 1 +
10 files changed, 1873 insertions(+), 555 deletions(-)
create mode 100644 drizzle/0025_greedy_krista_starr.sql
create mode 100644 drizzle/meta/0025_snapshot.json
diff --git a/drizzle/0025_greedy_krista_starr.sql b/drizzle/0025_greedy_krista_starr.sql
new file mode 100644
index 0000000..ca5e8f7
--- /dev/null
+++ b/drizzle/0025_greedy_krista_starr.sql
@@ -0,0 +1,2 @@
+ALTER TABLE "market_item_order" ADD COLUMN "marketItemId" integer NOT NULL;--> statement-breakpoint
+ALTER TABLE "market_item_order" ADD CONSTRAINT "market_item_order_marketItemId_market_item_id_fk" FOREIGN KEY ("marketItemId") REFERENCES "public"."market_item"("id") ON DELETE no action ON UPDATE no action;
\ No newline at end of file
diff --git a/drizzle/meta/0025_snapshot.json b/drizzle/meta/0025_snapshot.json
new file mode 100644
index 0000000..222158d
--- /dev/null
+++ b/drizzle/meta/0025_snapshot.json
@@ -0,0 +1,1248 @@
+{
+ "id": "df45bdcb-ea12-47e9-8d07-e4348aa43961",
+ "prevId": "530bbae3-07b0-4ea9-bb7e-3d249c2632d1",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.devlog": {
+ "name": "devlog",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "serial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "projectId": {
+ "name": "projectId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "timeSpent": {
+ "name": "timeSpent",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "deleted": {
+ "name": "deleted",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updatedAt": {
+ "name": "updatedAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "devlog_userId_user_id_fk": {
+ "name": "devlog_userId_user_id_fk",
+ "tableFrom": "devlog",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "devlog_projectId_project_id_fk": {
+ "name": "devlog_projectId_project_id_fk",
+ "tableFrom": "devlog",
+ "tableTo": "project",
+ "columnsFrom": [
+ "projectId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.impersonate_audit_log": {
+ "name": "impersonate_audit_log",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "serial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "adminUserId": {
+ "name": "adminUserId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "targetUserId": {
+ "name": "targetUserId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "timestamp": {
+ "name": "timestamp",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "impersonate_audit_log_adminUserId_user_id_fk": {
+ "name": "impersonate_audit_log_adminUserId_user_id_fk",
+ "tableFrom": "impersonate_audit_log",
+ "tableTo": "user",
+ "columnsFrom": [
+ "adminUserId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "impersonate_audit_log_targetUserId_user_id_fk": {
+ "name": "impersonate_audit_log_targetUserId_user_id_fk",
+ "tableFrom": "impersonate_audit_log",
+ "tableTo": "user",
+ "columnsFrom": [
+ "targetUserId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.legion_review": {
+ "name": "legion_review",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "serial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "projectId": {
+ "name": "projectId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "feedback": {
+ "name": "feedback",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "filamentUsed": {
+ "name": "filamentUsed",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "action": {
+ "name": "action",
+ "type": "legion_action",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "timestamp": {
+ "name": "timestamp",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "legion_review_userId_user_id_fk": {
+ "name": "legion_review_userId_user_id_fk",
+ "tableFrom": "legion_review",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "legion_review_projectId_project_id_fk": {
+ "name": "legion_review_projectId_project_id_fk",
+ "tableFrom": "legion_review",
+ "tableTo": "project",
+ "columnsFrom": [
+ "projectId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.market_item": {
+ "name": "market_item",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "serial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "createdBy": {
+ "name": "createdBy",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "minRequiredShopScore": {
+ "name": "minRequiredShopScore",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "minShopScore": {
+ "name": "minShopScore",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "maxShopScore": {
+ "name": "maxShopScore",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "maxPrice": {
+ "name": "maxPrice",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "minPrice": {
+ "name": "minPrice",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "isPublic": {
+ "name": "isPublic",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "deleted": {
+ "name": "deleted",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updatedAt": {
+ "name": "updatedAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "market_item_createdBy_user_id_fk": {
+ "name": "market_item_createdBy_user_id_fk",
+ "tableFrom": "market_item",
+ "tableTo": "user",
+ "columnsFrom": [
+ "createdBy"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.market_item_order": {
+ "name": "market_item_order",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "serial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "marketItemId": {
+ "name": "marketItemId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "addressId": {
+ "name": "addressId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "bricksPaid": {
+ "name": "bricksPaid",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "market_order_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'awaiting_approval'"
+ },
+ "userNotes": {
+ "name": "userNotes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted": {
+ "name": "deleted",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "market_item_order_userId_user_id_fk": {
+ "name": "market_item_order_userId_user_id_fk",
+ "tableFrom": "market_item_order",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "market_item_order_marketItemId_market_item_id_fk": {
+ "name": "market_item_order_marketItemId_market_item_id_fk",
+ "tableFrom": "market_item_order",
+ "tableTo": "market_item",
+ "columnsFrom": [
+ "marketItemId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.ovenpheus_log": {
+ "name": "ovenpheus_log",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "serial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "clay": {
+ "name": "clay",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "bricksReceived": {
+ "name": "bricksReceived",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "timestamp": {
+ "name": "timestamp",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "ovenpheus_log_userId_user_id_fk": {
+ "name": "ovenpheus_log_userId_user_id_fk",
+ "tableFrom": "ovenpheus_log",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.project": {
+ "name": "project",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "serial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "url": {
+ "name": "url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "editorFileType": {
+ "name": "editorFileType",
+ "type": "editor_file_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "editorUrl": {
+ "name": "editorUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "uploadedFileUrl": {
+ "name": "uploadedFileUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "modelFile": {
+ "name": "modelFile",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'building'"
+ },
+ "printedBy": {
+ "name": "printedBy",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "submittedToAirtable": {
+ "name": "submittedToAirtable",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "deleted": {
+ "name": "deleted",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updatedAt": {
+ "name": "updatedAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "project_userId_user_id_fk": {
+ "name": "project_userId_user_id_fk",
+ "tableFrom": "project",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "project_printedBy_user_id_fk": {
+ "name": "project_printedBy_user_id_fk",
+ "tableFrom": "project",
+ "tableTo": "user",
+ "columnsFrom": [
+ "printedBy"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.session": {
+ "name": "session",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "serial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expiresAt": {
+ "name": "expiresAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "session_userId_user_id_fk": {
+ "name": "session_userId_user_id_fk",
+ "tableFrom": "session",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.ship": {
+ "name": "ship",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "serial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "projectId": {
+ "name": "projectId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "url": {
+ "name": "url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "editorFileType": {
+ "name": "editorFileType",
+ "type": "editor_file_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "editorUrl": {
+ "name": "editorUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "uploadedFileUrl": {
+ "name": "uploadedFileUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "modelFile": {
+ "name": "modelFile",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "timestamp": {
+ "name": "timestamp",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "ship_userId_user_id_fk": {
+ "name": "ship_userId_user_id_fk",
+ "tableFrom": "ship",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "ship_projectId_project_id_fk": {
+ "name": "ship_projectId_project_id_fk",
+ "tableFrom": "ship",
+ "tableTo": "project",
+ "columnsFrom": [
+ "projectId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.t1_review": {
+ "name": "t1_review",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "serial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "projectId": {
+ "name": "projectId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "feedback": {
+ "name": "feedback",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "action": {
+ "name": "action",
+ "type": "t1_review_action",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "timestamp": {
+ "name": "timestamp",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "t1_review_userId_user_id_fk": {
+ "name": "t1_review_userId_user_id_fk",
+ "tableFrom": "t1_review",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "t1_review_projectId_project_id_fk": {
+ "name": "t1_review_projectId_project_id_fk",
+ "tableFrom": "t1_review",
+ "tableTo": "project",
+ "columnsFrom": [
+ "projectId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.t2_review": {
+ "name": "t2_review",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "serial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "projectId": {
+ "name": "projectId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "feedback": {
+ "name": "feedback",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "shopScoreMultiplier": {
+ "name": "shopScoreMultiplier",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 25
+ },
+ "timestamp": {
+ "name": "timestamp",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "t2_review_userId_user_id_fk": {
+ "name": "t2_review_userId_user_id_fk",
+ "tableFrom": "t2_review",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "t2_review_projectId_project_id_fk": {
+ "name": "t2_review_projectId_project_id_fk",
+ "tableFrom": "t2_review",
+ "tableTo": "project",
+ "columnsFrom": [
+ "projectId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user": {
+ "name": "user",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "serial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "idvId": {
+ "name": "idvId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "idvToken": {
+ "name": "idvToken",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "slackId": {
+ "name": "slackId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "profilePicture": {
+ "name": "profilePicture",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "hackatimeTrust": {
+ "name": "hackatimeTrust",
+ "type": "hackatime_trust",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "trust": {
+ "name": "trust",
+ "type": "trust",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'blue'"
+ },
+ "clay": {
+ "name": "clay",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "brick": {
+ "name": "brick",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "shopScore": {
+ "name": "shopScore",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "hasBasePrinter": {
+ "name": "hasBasePrinter",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "hasT1Review": {
+ "name": "hasT1Review",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "hasT2Review": {
+ "name": "hasT2Review",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "hasAdmin": {
+ "name": "hasAdmin",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "isPrinter": {
+ "name": "isPrinter",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "lastLoginAt": {
+ "name": "lastLoginAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_idvId_unique": {
+ "name": "user_idvId_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "idvId"
+ ]
+ },
+ "user_slackId_unique": {
+ "name": "user_slackId_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "slackId"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ }
+ },
+ "enums": {
+ "public.editor_file_type": {
+ "name": "editor_file_type",
+ "schema": "public",
+ "values": [
+ "url",
+ "upload"
+ ]
+ },
+ "public.hackatime_trust": {
+ "name": "hackatime_trust",
+ "schema": "public",
+ "values": [
+ "green",
+ "blue",
+ "yellow",
+ "red"
+ ]
+ },
+ "public.legion_action": {
+ "name": "legion_action",
+ "schema": "public",
+ "values": [
+ "mark_for_printing",
+ "unmark_for_printing",
+ "print",
+ "add_comment",
+ "reject",
+ "already_printed"
+ ]
+ },
+ "public.market_order_status": {
+ "name": "market_order_status",
+ "schema": "public",
+ "values": [
+ "awaiting_approval",
+ "fulfilled",
+ "denied",
+ "refunded"
+ ]
+ },
+ "public.project_audit_log_type": {
+ "name": "project_audit_log_type",
+ "schema": "public",
+ "values": [
+ "create",
+ "update",
+ "delete"
+ ]
+ },
+ "public.status": {
+ "name": "status",
+ "schema": "public",
+ "values": [
+ "building",
+ "submitted",
+ "t1_approved",
+ "printing",
+ "printed",
+ "t2_approved",
+ "finalized",
+ "rejected",
+ "rejected_locked"
+ ]
+ },
+ "public.t1_review_action": {
+ "name": "t1_review_action",
+ "schema": "public",
+ "values": [
+ "approve",
+ "approve_no_print",
+ "add_comment",
+ "reject",
+ "reject_lock"
+ ]
+ },
+ "public.trust": {
+ "name": "trust",
+ "schema": "public",
+ "values": [
+ "green",
+ "blue",
+ "yellow",
+ "red"
+ ]
+ }
+ },
+ "schemas": {},
+ "sequences": {},
+ "roles": {},
+ "policies": {},
+ "views": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json
index f350c57..c234f99 100644
--- a/drizzle/meta/_journal.json
+++ b/drizzle/meta/_journal.json
@@ -176,6 +176,13 @@
"when": 1767390464394,
"tag": "0024_bored_valeria_richards",
"breakpoints": true
+ },
+ {
+ "idx": 25,
+ "version": "7",
+ "when": 1768071572705,
+ "tag": "0025_greedy_krista_starr",
+ "breakpoints": true
}
]
}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index f6c020c..626ab37 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -984,7 +984,6 @@
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5",
@@ -3028,7 +3027,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
"integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
"license": "Apache-2.0",
- "peer": true,
"engines": {
"node": ">=8.0.0"
}
@@ -3050,7 +3048,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.2.0.tgz",
"integrity": "sha512-qRkLWiUEZNAmYapZ7KGS5C4OmBLcP/H2foXeOEaowYCR0wi89fHejrfYfbuLVCMLp/dWZXKvQusdbUEZjERfwQ==",
"license": "Apache-2.0",
- "peer": true,
"engines": {
"node": "^18.19.0 || >=20.6.0"
},
@@ -3063,7 +3060,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz",
"integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==",
"license": "Apache-2.0",
- "peer": true,
"dependencies": {
"@opentelemetry/semantic-conventions": "^1.29.0"
},
@@ -3079,7 +3075,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.208.0.tgz",
"integrity": "sha512-Eju0L4qWcQS+oXxi6pgh7zvE2byogAkcsVv0OjHF/97iOz1N/aKE6etSGowYkie+YA1uo6DNwdSxaaNnLvcRlA==",
"license": "Apache-2.0",
- "peer": true,
"dependencies": {
"@opentelemetry/api-logs": "0.208.0",
"import-in-the-middle": "^2.0.0",
@@ -3467,7 +3462,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.2.0.tgz",
"integrity": "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==",
"license": "Apache-2.0",
- "peer": true,
"dependencies": {
"@opentelemetry/core": "2.2.0",
"@opentelemetry/semantic-conventions": "^1.29.0"
@@ -3484,7 +3478,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.2.0.tgz",
"integrity": "sha512-xWQgL0Bmctsalg6PaXExmzdedSp3gyKV8mQBwK/j9VGdCDu2fmXIb2gAehBKbkXCpJ4HPkgv3QfoJWRT4dHWbw==",
"license": "Apache-2.0",
- "peer": true,
"dependencies": {
"@opentelemetry/core": "2.2.0",
"@opentelemetry/resources": "2.2.0",
@@ -3502,7 +3495,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz",
"integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==",
"license": "Apache-2.0",
- "peer": true,
"engines": {
"node": ">=14"
}
@@ -5309,7 +5301,6 @@
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.47.0.tgz",
"integrity": "sha512-mznN01MBXtr4T7X/E3ENkhF6GzqxTxL6/whG3OzCzUu8G8KYRNiCdoxLMVWAHJx/mDMPP3XAeKCMZHF/Xd/CDw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@standard-schema/spec": "^1.0.0",
"@sveltejs/acorn-typescript": "^1.0.5",
@@ -5348,7 +5339,6 @@
"resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.1.tgz",
"integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@sveltejs/vite-plugin-svelte-inspector": "^5.0.0",
"debug": "^4.4.1",
@@ -5855,7 +5845,6 @@
"integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.46.1",
"@typescript-eslint/types": "8.46.1",
@@ -6111,7 +6100,6 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT",
- "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -6388,7 +6376,6 @@
}
],
"license": "MIT",
- "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.8.25",
"caniuse-lite": "^1.0.30001754",
@@ -7002,7 +6989,6 @@
"integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==",
"hasInstallScript": true,
"license": "MIT",
- "peer": true,
"bin": {
"esbuild": "bin/esbuild"
},
@@ -7099,7 +7085,6 @@
"integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -9399,7 +9384,6 @@
"resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz",
"integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"pg-connection-string": "^2.9.1",
"pg-pool": "^3.10.1",
@@ -9521,7 +9505,6 @@
}
],
"license": "MIT",
- "peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -9694,7 +9677,6 @@
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -9711,7 +9693,6 @@
"integrity": "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"peerDependencies": {
"prettier": "^3.0.0",
"svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0"
@@ -10017,7 +9998,6 @@
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz",
"integrity": "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@types/estree": "1.0.8"
},
@@ -10595,7 +10575,6 @@
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.40.1.tgz",
"integrity": "sha512-0R3t2oiLxJNJb2buz61MNfPdkjeyj2qTCM7TtIv/4ZfF12zD7Ig8iIo+C8febroy+9S4QJ7qfijtearSdO/1ww==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@jridgewell/remapping": "^2.3.4",
"@jridgewell/sourcemap-codec": "^1.5.0",
@@ -10688,8 +10667,7 @@
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz",
"integrity": "sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/tapable": {
"version": "2.3.0",
@@ -10854,7 +10832,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
- "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -10913,7 +10890,6 @@
"resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.21.tgz",
"integrity": "sha512-Wj7/AMtE9MRnAXa6Su3Lk0LNCfqDYgfwVjwRFVum9U7wsto1imuHqk4kTm7Jni+5A0Hn7dttL6O/zjvUvoo+8A==",
"license": "MIT",
- "peer": true,
"dependencies": {
"defu": "^6.1.4",
"exsolve": "^1.0.7",
@@ -11064,7 +11040,6 @@
"resolved": "https://registry.npmjs.org/vite/-/vite-7.1.10.tgz",
"integrity": "sha512-CmuvUBzVJ/e3HGxhg6cYk88NGgTnBoOo7ogtfJJ0fefUWAxN/WDSUa50o+oVBxuIhO8FoEZW0j2eW7sfjs5EtA==",
"license": "MIT",
- "peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.5.0",
@@ -11640,7 +11615,6 @@
"integrity": "sha512-HwaJmXO3M1r4S8x2ea2vy8Rw/y/38HRQuK/gNDRQ7w9cJXn6xSl1sIIqKCffULSUjul3wV3I3Nd/GfbmsRReEA==",
"hasInstallScript": true,
"license": "Apache-2.0",
- "peer": true,
"bin": {
"workerd": "bin/workerd"
},
diff --git a/src/lib/server/db/schema.ts b/src/lib/server/db/schema.ts
index 2f4591e..977dfe9 100644
--- a/src/lib/server/db/schema.ts
+++ b/src/lib/server/db/schema.ts
@@ -249,6 +249,7 @@ export const marketOrderStatus = pgEnum('market_order_status', [
export const marketItemOrder = pgTable('market_item_order', {
id: serial().primaryKey(),
userId: integer().references(() => user.id).notNull(),
+ marketItemId: integer().references(() => marketItem.id).notNull(),
addressId: text().notNull(),
bricksPaid: integer().notNull(),
diff --git a/src/routes/dashboard/admin/admin/orders/+page.server.ts b/src/routes/dashboard/admin/admin/orders/+page.server.ts
index 64b2711..c89b8dc 100644
--- a/src/routes/dashboard/admin/admin/orders/+page.server.ts
+++ b/src/routes/dashboard/admin/admin/orders/+page.server.ts
@@ -1,26 +1,28 @@
import { db } from '$lib/server/db/index.js';
-import { project, user, devlog } from '$lib/server/db/schema.js';
+import { marketItemOrder, marketItem, user } from '$lib/server/db/schema.js';
import { error } from '@sveltejs/kit';
-import { eq, and, sql, ne, inArray } from 'drizzle-orm';
+import { eq, and, ne, inArray, sql, desc } from 'drizzle-orm';
import type { Actions } from './$types';
+import { decrypt } from '$lib/server/encryption';
+import { getUserData } from '$lib/server/idvUserData';
export async function load({ locals }) {
if (!locals.user) {
throw error(500);
}
- if (!locals.user.hasT2Review) {
+ if (!locals.user.hasAdmin) {
throw error(403, { message: 'oi get out' });
}
- const projects = await getProjects(['printed'], [], []);
+ const orders = await getOrders([], [], [], []);
- const allProjects = await db
+ const allMarketItems = await db
.select({
- id: project.id,
- name: project.name
+ id: marketItem.id,
+ name: marketItem.name
})
- .from(project)
- .where(and(eq(project.deleted, false)));
+ .from(marketItem)
+ .where(eq(marketItem.deleted, false));
const users = await db
.select({
@@ -30,10 +32,44 @@ export async function load({ locals }) {
.from(user)
.where(and(ne(user.trust, 'red'), ne(user.hackatimeTrust, 'red'))); // hide banned users
+ // Get unique countries from orders
+ const ordersWithAddresses = await db
+ .select({
+ userId: marketItemOrder.userId,
+ addressId: marketItemOrder.addressId
+ })
+ .from(marketItemOrder)
+ .where(eq(marketItemOrder.deleted, false));
+
+ const countries: string[] = [];
+ for (const order of ordersWithAddresses) {
+ try {
+ const orderUser = await db
+ .select({
+ idvToken: user.idvToken
+ })
+ .from(user)
+ .where(eq(user.id, order.userId))
+ .limit(1);
+
+ if (orderUser[0]?.idvToken) {
+ const token = decrypt(orderUser[0].idvToken);
+ const userData = await getUserData(token);
+ const address = userData?.addresses?.find((a: { id: string }) => a.id === order.addressId);
+ if (address?.country && !countries.includes(address.country)) {
+ countries.push(address.country);
+ }
+ }
+ } catch {
+ // Skip if we can't fetch address
+ }
+ }
+
return {
- allProjects,
- projects,
- users
+ allMarketItems,
+ orders,
+ users,
+ countries: countries.sort()
};
}
@@ -42,79 +78,103 @@ export const actions = {
if (!locals.user) {
throw error(500);
}
- if (!locals.user.hasT2Review) {
+ if (!locals.user.hasAdmin) {
throw error(403, { message: 'oi get out' });
}
const data = await request.formData();
- const statusFilter = data.getAll('status') as (typeof project.status._.data)[];
+ const statusFilter = data.getAll('status') as (typeof marketItemOrder.status._.data)[];
- const projectFilter = data.getAll('project').map((projectId) => {
- const parsedInt = parseInt(projectId.toString());
- if (!parsedInt) throw error(400, { message: 'malformed project filter' });
- return parseInt(projectId.toString());
+ const marketItemFilter = data.getAll('marketItem').map((itemId) => {
+ const parsedInt = parseInt(itemId.toString());
+ if (!parsedInt) throw error(400, { message: 'malformed market item filter' });
+ return parsedInt;
});
const userFilter = data.getAll('user').map((userId) => {
const parsedInt = parseInt(userId.toString());
if (!parsedInt) throw error(400, { message: 'malformed user filter' });
- return parseInt(userId.toString());
+ return parsedInt;
});
- const projects = await getProjects(statusFilter, projectFilter, userFilter);
+ const countryFilter = data.getAll('country') as string[];
+
+ const orders = await getOrders(statusFilter, marketItemFilter, userFilter, countryFilter);
return {
- projects,
+ orders,
fields: {
status: statusFilter,
- project: projectFilter,
- user: userFilter
+ marketItem: marketItemFilter,
+ user: userFilter,
+ country: countryFilter
}
};
}
} satisfies Actions;
-async function getProjects(
- statusFilter: (typeof project.status._.data)[],
- projectFilter: number[],
- userFilter: number[]
+async function getOrders(
+ statusFilter: (typeof marketItemOrder.status._.data)[],
+ marketItemFilter: number[],
+ userFilter: number[],
+ countryFilter: string[]
) {
- return await db
+ const baseOrders = await db
.select({
- project: {
- id: project.id,
- name: project.name,
- description: project.description,
- url: project.url,
- createdAt: project.createdAt,
- status: project.status
+ order: {
+ id: marketItemOrder.id,
+ userId: marketItemOrder.userId,
+ marketItemId: marketItemOrder.marketItemId,
+ addressId: marketItemOrder.addressId,
+ bricksPaid: marketItemOrder.bricksPaid,
+ status: marketItemOrder.status,
+ userNotes: marketItemOrder.userNotes,
+ notes: marketItemOrder.notes,
+ createdAt: marketItemOrder.createdAt
+ },
+ marketItem: {
+ id: marketItem.id,
+ name: marketItem.name,
+ image: marketItem.image
},
user: {
id: user.id,
- name: user.name
- },
- timeSpent: sql
+ Order is {marketOrderStatuses[data.orderData.order.status].toLowerCase()}. No actions available. +
+ {/if} ++
Bricks paid: {order.order.bricksPaid}
-- Ordered + Ordered {relativeDate(order.order.createdAt)}
diff --git a/src/routes/dashboard/admin/admin/orders/[id]/+page.server.ts b/src/routes/dashboard/admin/admin/orders/[id]/+page.server.ts index 7193ef8..8fb97da 100644 --- a/src/routes/dashboard/admin/admin/orders/[id]/+page.server.ts +++ b/src/routes/dashboard/admin/admin/orders/[id]/+page.server.ts @@ -62,7 +62,9 @@ export async function load({ locals, params }) { try { const token = decrypt(orderData.user.idvToken); const userData = await getUserData(token); - address = userData?.addresses?.find((a: { id: string }) => a.id === orderData.order.addressId); + address = userData?.addresses?.find( + (a: { id: string }) => a.id === orderData.order.addressId + ); } catch { userDataError = true; } @@ -124,7 +126,7 @@ export const actions = { const notesText = orderData.order.notes ? `\n\nNotes: ${orderData.order.notes}` : ''; await sendSlackDM( orderData.user.slackId, - `Your order for ${orderData.marketItem?.name || 'a market item'} has been shipped! :package:${notesText}` + `Your order for ${orderData.marketItem?.name || 'a market item'} just got shipped! :package: :package: :package:\n\n${notesText}` ); } @@ -186,14 +188,14 @@ export const actions = { if (orderData.user?.slackId) { await sendSlackDM( orderData.user.slackId, - `Your order for ${orderData.marketItem?.name || 'a market item'} has been refunded. You received ${orderData.order.bricksPaid} bricks back.` + `Your order for ${orderData.marketItem?.name || 'a market item'} has been refunded! :oop:\nYou got your ${orderData.order.bricksPaid} bricks back` ); } return { success: true, message: 'Order refunded' }; }, - delete: async ({ locals, params }) => { + deny: async ({ locals, params }) => { if (!locals.user) { throw error(500); } @@ -225,19 +227,18 @@ export const actions = { throw error(404, { message: 'order not found' }); } - // Mark order as denied (deleted without refund) + // Mark order as denied await db .update(marketItemOrder) .set({ - status: 'denied', - deleted: true + status: 'denied' }) .where(eq(marketItemOrder.id, id)); if (orderData.user?.slackId) { await sendSlackDM( orderData.user.slackId, - `Your order for ${orderData.marketItem?.name || 'a market item'} has been denied.` + `Your order for ${orderData.marketItem?.name || 'a market item'} has been denied :dcolon:\nYou didn't get any of your bricks back :hmmm:` ); } diff --git a/src/routes/dashboard/admin/admin/orders/[id]/+page.svelte b/src/routes/dashboard/admin/admin/orders/[id]/+page.svelte index 3bfb120..f1dfe0a 100644 --- a/src/routes/dashboard/admin/admin/orders/[id]/+page.svelte +++ b/src/routes/dashboard/admin/admin/orders/[id]/+page.svelte @@ -15,91 +15,98 @@ }; -{data.orderData.marketItem?.name}
-{data.orderData.marketItem?.description}
-- - {data.orderData.user?.name} - -
- {#if data.orderData.user?.slackId} +{data.orderData.marketItem?.name}
+{data.orderData.marketItem?.description}
+- Slack ID: {data.orderData.user.slackId} + + {data.orderData.user?.name} +
- {/if} -Bricks paid: {data.orderData.order.bricksPaid}
-+ Slack ID: {data.orderData.user.slackId} +
+ {/if} +Bricks paid: {data.orderData.order.bricksPaid}
+{marketOrderStatuses[data.orderData.order.status]}
+Failed to fetch user data, ask them to re-login
+ {:else if data.address} +{data.address.line_1}
+ {#if data.address.line_2} +{data.address.line_2}
+ {/if} ++ {data.address.city}, {data.address.state}, + {data.address.postal_code} +
+{data.address.country}
+ {:else} +Address not found
+ {/if} +{marketOrderStatuses[data.orderData.order.status]}
-{data.orderData.order.userNotes || 'None'}
+Error fetching address data
- {:else if data.address} -{data.address.line_1}
- {#if data.address.line_2} -{data.address.line_2}
- {/if} +- {data.address.city}, {data.address.state} {data.address.postal_code} + Created + {relativeDate(data.orderData.order.createdAt)} +
-{data.address.country}
- {:else} -Address not found
- {/if} -{data.orderData.order.userNotes || 'None'}
+- Created - {relativeDate(data.orderData.order.createdAt)} - -
+ {#if data.orderData.marketItem?.image} +You'll get {bricks} bricks
++ You'll get {bricks} bricks and have {Math.floor(data.user.clay - clay)} left +