From 3ad7fc2e690b067a3db60f9317949c5e6a2e3426 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E3=81=97=E3=81=BF?=
<37952374+Simirall@users.noreply.github.com>
Date: Mon, 19 Aug 2024 21:40:17 +0900
Subject: [PATCH] Feat: Madamis crud (#1)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* update: add madamis pl, gm column
* feat: add madamis ui
* madamis create
* feat: edit madamis
* delete madamis
* fix: ただしいgrouping routes
* feat: add loading
---
migrations/0001_classy_shard.sql | 2 +
migrations/meta/0001_snapshot.json | 192 ++++++++++++
migrations/meta/_journal.json | 7 +
package.json | 11 +-
pnpm-lock.yaml | 420 ++++++++++++++++++++++++++
schema.ts | 2 +
src/api.ts | 11 +-
src/apis/madamis.ts | 52 ++++
src/apis/user.ts | 12 +
src/client.tsx | 19 +-
src/component.tsx | 15 -
src/index.tsx | 15 +-
src/pages/App.tsx | 18 ++
src/pages/components/AddMadamis.tsx | 23 ++
src/pages/components/Header.tsx | 34 +++
src/pages/components/MadamisList.tsx | 63 ++++
src/pages/components/MadamisModal.tsx | 181 +++++++++++
src/pages/hooks/useMadamisList.tsx | 15 +
src/pages/stores/madamisModalStore.ts | 22 ++
19 files changed, 1083 insertions(+), 31 deletions(-)
create mode 100644 migrations/0001_classy_shard.sql
create mode 100644 migrations/meta/0001_snapshot.json
create mode 100644 src/apis/madamis.ts
create mode 100644 src/apis/user.ts
delete mode 100644 src/component.tsx
create mode 100644 src/pages/App.tsx
create mode 100644 src/pages/components/AddMadamis.tsx
create mode 100644 src/pages/components/Header.tsx
create mode 100644 src/pages/components/MadamisList.tsx
create mode 100644 src/pages/components/MadamisModal.tsx
create mode 100644 src/pages/hooks/useMadamisList.tsx
create mode 100644 src/pages/stores/madamisModalStore.ts
diff --git a/migrations/0001_classy_shard.sql b/migrations/0001_classy_shard.sql
new file mode 100644
index 0000000..0f0ece8
--- /dev/null
+++ b/migrations/0001_classy_shard.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `Madamis` ADD `player` integer NOT NULL;--> statement-breakpoint
+ALTER TABLE `Madamis` ADD `gmRequired` integer NOT NULL;
\ No newline at end of file
diff --git a/migrations/meta/0001_snapshot.json b/migrations/meta/0001_snapshot.json
new file mode 100644
index 0000000..0192336
--- /dev/null
+++ b/migrations/meta/0001_snapshot.json
@@ -0,0 +1,192 @@
+{
+ "version": "6",
+ "dialect": "sqlite",
+ "id": "41052890-ad09-43a6-baa9-0048bf340820",
+ "prevId": "e9e38636-7650-4a2a-979b-236f8e3be152",
+ "tables": {
+ "GameUsers": {
+ "name": "GameUsers",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "gameId": {
+ "name": "gameId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "GameUsers_gameId_Games_id_fk": {
+ "name": "GameUsers_gameId_Games_id_fk",
+ "tableFrom": "GameUsers",
+ "tableTo": "Games",
+ "columnsFrom": [
+ "gameId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "GameUsers_userId_Users_id_fk": {
+ "name": "GameUsers_userId_Users_id_fk",
+ "tableFrom": "GameUsers",
+ "tableTo": "Users",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "Games": {
+ "name": "Games",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "date": {
+ "name": "date",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "madamisId": {
+ "name": "madamisId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "Games_madamisId_Madamis_id_fk": {
+ "name": "Games_madamisId_Madamis_id_fk",
+ "tableFrom": "Games",
+ "tableTo": "Madamis",
+ "columnsFrom": [
+ "madamisId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "Madamis": {
+ "name": "Madamis",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "link": {
+ "name": "link",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "player": {
+ "name": "player",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "gmRequired": {
+ "name": "gmRequired",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "Users": {
+ "name": "Users",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "color": {
+ "name": "color",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ }
+ },
+ "enums": {},
+ "_meta": {
+ "schemas": {},
+ "tables": {},
+ "columns": {}
+ },
+ "internal": {
+ "indexes": {}
+ }
+}
\ No newline at end of file
diff --git a/migrations/meta/_journal.json b/migrations/meta/_journal.json
index 9135378..5476f5b 100644
--- a/migrations/meta/_journal.json
+++ b/migrations/meta/_journal.json
@@ -8,6 +8,13 @@
"when": 1723995111132,
"tag": "0000_fair_hammerhead",
"breakpoints": true
+ },
+ {
+ "idx": 1,
+ "version": "6",
+ "when": 1724043283043,
+ "tag": "0001_classy_shard",
+ "breakpoints": true
}
]
}
\ No newline at end of file
diff --git a/package.json b/package.json
index 0dd995c..17e273f 100644
--- a/package.json
+++ b/package.json
@@ -12,10 +12,19 @@
},
"dependencies": {
"@hono/react-renderer": "^0.2.1",
+ "@hono/zod-validator": "^0.2.2",
+ "@hookform/resolvers": "^3.9.0",
+ "@mantine/core": "^7.12.1",
+ "@mantine/hooks": "^7.12.1",
+ "@phosphor-icons/react": "^2.1.7",
"drizzle-orm": "^0.33.0",
"hono": "^4.5.6",
"react": "^18.3.1",
- "react-dom": "^18.3.1"
+ "react-dom": "^18.3.1",
+ "react-hook-form": "^7.52.2",
+ "swr": "^2.2.5",
+ "zod": "^3.23.8",
+ "zustand": "^4.5.5"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20240529.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c816c3c..3192bd1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -11,6 +11,21 @@ importers:
'@hono/react-renderer':
specifier: ^0.2.1
version: 0.2.1(hono@4.5.6)
+ '@hono/zod-validator':
+ specifier: ^0.2.2
+ version: 0.2.2(hono@4.5.6)(zod@3.23.8)
+ '@hookform/resolvers':
+ specifier: ^3.9.0
+ version: 3.9.0(react-hook-form@7.52.2(react@18.3.1))
+ '@mantine/core':
+ specifier: ^7.12.1
+ version: 7.12.1(@mantine/hooks@7.12.1(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@mantine/hooks':
+ specifier: ^7.12.1
+ version: 7.12.1(react@18.3.1)
+ '@phosphor-icons/react':
+ specifier: ^2.1.7
+ version: 2.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
drizzle-orm:
specifier: ^0.33.0
version: 0.33.0(@cloudflare/workers-types@4.20240815.0)(@prisma/client@5.18.0)(@types/react@18.3.3)(react@18.3.1)
@@ -23,6 +38,18 @@ importers:
react-dom:
specifier: ^18.3.1
version: 18.3.1(react@18.3.1)
+ react-hook-form:
+ specifier: ^7.52.2
+ version: 7.52.2(react@18.3.1)
+ swr:
+ specifier: ^2.2.5
+ version: 2.2.5(react@18.3.1)
+ zod:
+ specifier: ^3.23.8
+ version: 3.23.8
+ zustand:
+ specifier: ^4.5.5
+ version: 4.5.5(@types/react@18.3.3)(react@18.3.1)
devDependencies:
'@cloudflare/workers-types':
specifier: ^4.20240529.0
@@ -54,6 +81,10 @@ importers:
packages:
+ '@babel/runtime@7.25.0':
+ resolution: {integrity: sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==}
+ engines: {node: '>=6.9.0'}
+
'@cloudflare/kv-asset-handler@0.3.4':
resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==}
engines: {node: '>=16.13'}
@@ -662,6 +693,27 @@ packages:
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
engines: {node: '>=14'}
+ '@floating-ui/core@1.6.7':
+ resolution: {integrity: sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==}
+
+ '@floating-ui/dom@1.6.10':
+ resolution: {integrity: sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==}
+
+ '@floating-ui/react-dom@2.1.1':
+ resolution: {integrity: sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==}
+ peerDependencies:
+ react: '>=16.8.0'
+ react-dom: '>=16.8.0'
+
+ '@floating-ui/react@0.26.22':
+ resolution: {integrity: sha512-LNv4azPt8SpT4WW7Kku5JNVjLk2GcS0bGGjFTAgqOONRFo9r/aaGHHPpdiIuQbB1t8shmWyWqTTUDmZ9fcNshg==}
+ peerDependencies:
+ react: '>=16.8.0'
+ react-dom: '>=16.8.0'
+
+ '@floating-ui/utils@0.2.7':
+ resolution: {integrity: sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==}
+
'@hono/node-server@1.12.0':
resolution: {integrity: sha512-e6oHjNiErRxsZRZBmc2KucuvY3btlO/XPncIpP2X75bRdTilF9GLjm3NHvKKunpJbbJJj31/FoPTksTf8djAVw==}
engines: {node: '>=18.14.1'}
@@ -684,6 +736,17 @@ packages:
peerDependencies:
hono: '*'
+ '@hono/zod-validator@0.2.2':
+ resolution: {integrity: sha512-dSDxaPV70Py8wuIU2QNpoVEIOSzSXZ/6/B/h4xA7eOMz7+AarKTSGV8E6QwrdcCbBLkpqfJ4Q2TmBO0eP1tCBQ==}
+ peerDependencies:
+ hono: '>=3.9.0'
+ zod: ^3.19.1
+
+ '@hookform/resolvers@3.9.0':
+ resolution: {integrity: sha512-bU0Gr4EepJ/EQsH/IwEzYLsT/PEj5C0ynLQ4m+GSHS+xKH4TfSelhluTgOaoc4kA5s7eCsQbM4wvZLzELmWzUg==}
+ peerDependencies:
+ react-hook-form: ^7.0.0
+
'@jridgewell/resolve-uri@3.1.2':
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'}
@@ -694,6 +757,25 @@ packages:
'@jridgewell/trace-mapping@0.3.9':
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
+ '@mantine/core@7.12.1':
+ resolution: {integrity: sha512-PXKIDaT1fpNB77dPQIcdFGM2NRnfmsJSVx3uuBccngBQWMIWI0wPyiO1Y26DK4LQrbrypeb+TS+Zxpgx6RoiCA==}
+ peerDependencies:
+ '@mantine/hooks': 7.12.1
+ react: ^18.2.0
+ react-dom: ^18.2.0
+
+ '@mantine/hooks@7.12.1':
+ resolution: {integrity: sha512-YPA3qiMHJkWID5+YzakBaLvjHtX3Fg3PdPY49iIb/CaWM9+lrJ+77TOVS7bsY7ZTBHXUfzft1/6Woqt3xSuweA==}
+ peerDependencies:
+ react: ^18.2.0
+
+ '@phosphor-icons/react@2.1.7':
+ resolution: {integrity: sha512-g2e2eVAn1XG2a+LI09QU3IORLhnFNAFkNbo2iwbX6NOKSLOwvEMmTa7CgOzEbgNWR47z8i8kwjdvYZ5fkGx1mQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ react: '>= 16.8'
+ react-dom: '>= 16.8'
+
'@prisma/client@5.18.0':
resolution: {integrity: sha512-BWivkLh+af1kqC89zCJYkHsRcyWsM8/JHpsDMM76DjP3ZdEquJhXa4IeX+HkWPnwJ5FanxEJFZZDTWiDs/Kvyw==}
engines: {node: '>=16.13'}
@@ -844,6 +926,13 @@ packages:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
+ client-only@0.0.1:
+ resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
+
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
consola@3.2.3:
resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==}
engines: {node: ^14.18.0 || >=16.10.0}
@@ -873,6 +962,9 @@ packages:
defu@6.1.4:
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
+ detect-node-es@1.1.0:
+ resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
+
drizzle-kit@0.24.0:
resolution: {integrity: sha512-rUl5Rf5HLOVkAwHEVEi8xgulIRWzoys0q77RHGCxv5e9v8AI3JGFg7Ug5K1kn513RwNZbuNJMUKOXo0j8kPRgg==}
hasBin: true
@@ -1014,6 +1106,10 @@ packages:
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+ get-nonce@1.0.1:
+ resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
+ engines: {node: '>=6'}
+
get-source@2.0.12:
resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==}
@@ -1035,6 +1131,9 @@ packages:
resolution: {integrity: sha512-9SuUC/zLQv8YAcnIxJko0KCeLI0Q6menPsDWuJ9jaH+r8ZkVXeLqeLs1QJXCPKKbURAWj9x0SJBSFh803EnAUw==}
engines: {node: '>=16.0.0'}
+ invariant@2.2.4:
+ resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
+
is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
@@ -1102,6 +1201,10 @@ packages:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
@@ -1130,11 +1233,65 @@ packages:
printable-characters@1.0.42:
resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==}
+ prop-types@15.8.1:
+ resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
+
react-dom@18.3.1:
resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
peerDependencies:
react: ^18.3.1
+ react-hook-form@7.52.2:
+ resolution: {integrity: sha512-pqfPEbERnxxiNMPd0bzmt1tuaPcVccywFDpyk2uV5xCIBphHV5T8SVnX9/o3kplPE1zzKt77+YIoq+EMwJp56A==}
+ engines: {node: '>=18.0.0'}
+ peerDependencies:
+ react: ^16.8.0 || ^17 || ^18 || ^19
+
+ react-is@16.13.1:
+ resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
+
+ react-number-format@5.4.0:
+ resolution: {integrity: sha512-NWdICrqLhI7rAS8yUeLVd6Wr4cN7UjJ9IBTS0f/a9i7UB4x4Ti70kGnksBtZ7o4Z7YRbvCMMR/jQmkoOBa/4fg==}
+ peerDependencies:
+ react: ^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
+ react-dom: ^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
+
+ react-remove-scroll-bar@2.3.6:
+ resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-remove-scroll@2.5.10:
+ resolution: {integrity: sha512-m3zvBRANPBw3qxVVjEIPEQinkcwlFZ4qyomuWVpNJdv4c6MvHfXV0C3L9Jx5rr3HeBHKNRX+1jreB5QloDIJjA==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-style-singleton@2.2.1:
+ resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-textarea-autosize@8.5.3:
+ resolution: {integrity: sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+
react@18.3.1:
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
engines: {node: '>=0.10.0'}
@@ -1143,6 +1300,9 @@ packages:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
+ regenerator-runtime@0.14.1:
+ resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
+
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
@@ -1202,6 +1362,14 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
+ swr@2.2.5:
+ resolution: {integrity: sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==}
+ peerDependencies:
+ react: ^16.11.0 || ^17.0.0 || ^18.0.0
+
+ tabbable@6.2.0:
+ resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
+
to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@@ -1209,6 +1377,10 @@ packages:
tslib@2.6.3:
resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==}
+ type-fest@4.25.0:
+ resolution: {integrity: sha512-bRkIGlXsnGBRBQRAY56UXBm//9qH4bmJfFvq83gSz41N282df+fjy8ofcEgc1sM8geNt5cl6mC2g9Fht1cs8Aw==}
+ engines: {node: '>=16'}
+
ufo@1.5.4:
resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==}
@@ -1222,6 +1394,54 @@ packages:
unenv-nightly@1.10.0-1717606461.a117952:
resolution: {integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==}
+ use-callback-ref@1.3.2:
+ resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ use-composed-ref@1.3.0:
+ resolution: {integrity: sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+
+ use-isomorphic-layout-effect@1.1.2:
+ resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ use-latest@1.2.1:
+ resolution: {integrity: sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ use-sidecar@1.1.2:
+ resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ use-sync-external-store@1.2.2:
+ resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+
vite@5.4.1:
resolution: {integrity: sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA==}
engines: {node: ^18.0.0 || >=20.0.0}
@@ -1289,8 +1509,27 @@ packages:
zod@3.23.8:
resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
+ zustand@4.5.5:
+ resolution: {integrity: sha512-+0PALYNJNgK6hldkgDq2vLrw5f6g/jCInz52n9RTpropGgeAf/ioFUCdtsjCqu4gNhW9D01rUQBROoRjdzyn2Q==}
+ engines: {node: '>=12.7.0'}
+ peerDependencies:
+ '@types/react': '>=16.8'
+ immer: '>=9.0.6'
+ react: '>=16.8'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ immer:
+ optional: true
+ react:
+ optional: true
+
snapshots:
+ '@babel/runtime@7.25.0':
+ dependencies:
+ regenerator-runtime: 0.14.1
+
'@cloudflare/kv-asset-handler@0.3.4':
dependencies:
mime: 3.0.0
@@ -1612,6 +1851,31 @@ snapshots:
'@fastify/busboy@2.1.1': {}
+ '@floating-ui/core@1.6.7':
+ dependencies:
+ '@floating-ui/utils': 0.2.7
+
+ '@floating-ui/dom@1.6.10':
+ dependencies:
+ '@floating-ui/core': 1.6.7
+ '@floating-ui/utils': 0.2.7
+
+ '@floating-ui/react-dom@2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@floating-ui/dom': 1.6.10
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+
+ '@floating-ui/react@0.26.22(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@floating-ui/react-dom': 2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@floating-ui/utils': 0.2.7
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ tabbable: 6.2.0
+
+ '@floating-ui/utils@0.2.7': {}
+
'@hono/node-server@1.12.0': {}
'@hono/react-renderer@0.2.1(hono@4.5.6)':
@@ -1633,6 +1897,15 @@ snapshots:
- supports-color
- utf-8-validate
+ '@hono/zod-validator@0.2.2(hono@4.5.6)(zod@3.23.8)':
+ dependencies:
+ hono: 4.5.6
+ zod: 3.23.8
+
+ '@hookform/resolvers@3.9.0(react-hook-form@7.52.2(react@18.3.1))':
+ dependencies:
+ react-hook-form: 7.52.2(react@18.3.1)
+
'@jridgewell/resolve-uri@3.1.2': {}
'@jridgewell/sourcemap-codec@1.5.0': {}
@@ -1642,6 +1915,29 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0
+ '@mantine/core@7.12.1(@mantine/hooks@7.12.1(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@floating-ui/react': 0.26.22(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@mantine/hooks': 7.12.1(react@18.3.1)
+ clsx: 2.1.1
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ react-number-format: 5.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react-remove-scroll: 2.5.10(@types/react@18.3.3)(react@18.3.1)
+ react-textarea-autosize: 8.5.3(@types/react@18.3.3)(react@18.3.1)
+ type-fest: 4.25.0
+ transitivePeerDependencies:
+ - '@types/react'
+
+ '@mantine/hooks@7.12.1(react@18.3.1)':
+ dependencies:
+ react: 18.3.1
+
+ '@phosphor-icons/react@2.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+
'@prisma/client@5.18.0':
optional: true
@@ -1764,6 +2060,10 @@ snapshots:
optionalDependencies:
fsevents: 2.3.3
+ client-only@0.0.1: {}
+
+ clsx@2.1.1: {}
+
consola@3.2.3: {}
cookie@0.5.0: {}
@@ -1780,6 +2080,8 @@ snapshots:
defu@6.1.4: {}
+ detect-node-es@1.1.0: {}
+
drizzle-kit@0.24.0:
dependencies:
'@drizzle-team/brocli': 0.8.2
@@ -1920,6 +2222,8 @@ snapshots:
function-bind@1.1.2: {}
+ get-nonce@1.0.1: {}
+
get-source@2.0.12:
dependencies:
data-uri-to-buffer: 2.0.2
@@ -1941,6 +2245,10 @@ snapshots:
hono@4.5.6: {}
+ invariant@2.2.4:
+ dependencies:
+ loose-envify: 1.4.0
+
is-binary-path@2.1.0:
dependencies:
binary-extensions: 2.3.0
@@ -2004,6 +2312,8 @@ snapshots:
normalize-path@3.0.0: {}
+ object-assign@4.1.1: {}
+
path-parse@1.0.7: {}
path-to-regexp@6.2.2: {}
@@ -2024,12 +2334,67 @@ snapshots:
printable-characters@1.0.42: {}
+ prop-types@15.8.1:
+ dependencies:
+ loose-envify: 1.4.0
+ object-assign: 4.1.1
+ react-is: 16.13.1
+
react-dom@18.3.1(react@18.3.1):
dependencies:
loose-envify: 1.4.0
react: 18.3.1
scheduler: 0.23.2
+ react-hook-form@7.52.2(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+
+ react-is@16.13.1: {}
+
+ react-number-format@5.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+ dependencies:
+ prop-types: 15.8.1
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+
+ react-remove-scroll-bar@2.3.6(@types/react@18.3.3)(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+ react-style-singleton: 2.2.1(@types/react@18.3.3)(react@18.3.1)
+ tslib: 2.6.3
+ optionalDependencies:
+ '@types/react': 18.3.3
+
+ react-remove-scroll@2.5.10(@types/react@18.3.3)(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+ react-remove-scroll-bar: 2.3.6(@types/react@18.3.3)(react@18.3.1)
+ react-style-singleton: 2.2.1(@types/react@18.3.3)(react@18.3.1)
+ tslib: 2.6.3
+ use-callback-ref: 1.3.2(@types/react@18.3.3)(react@18.3.1)
+ use-sidecar: 1.1.2(@types/react@18.3.3)(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.3
+
+ react-style-singleton@2.2.1(@types/react@18.3.3)(react@18.3.1):
+ dependencies:
+ get-nonce: 1.0.1
+ invariant: 2.2.4
+ react: 18.3.1
+ tslib: 2.6.3
+ optionalDependencies:
+ '@types/react': 18.3.3
+
+ react-textarea-autosize@8.5.3(@types/react@18.3.3)(react@18.3.1):
+ dependencies:
+ '@babel/runtime': 7.25.0
+ react: 18.3.1
+ use-composed-ref: 1.3.0(react@18.3.1)
+ use-latest: 1.2.1(@types/react@18.3.3)(react@18.3.1)
+ transitivePeerDependencies:
+ - '@types/react'
+
react@18.3.1:
dependencies:
loose-envify: 1.4.0
@@ -2038,6 +2403,8 @@ snapshots:
dependencies:
picomatch: 2.3.1
+ regenerator-runtime@0.14.1: {}
+
resolve-pkg-maps@1.0.0: {}
resolve.exports@2.0.2: {}
@@ -2113,12 +2480,22 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
+ swr@2.2.5(react@18.3.1):
+ dependencies:
+ client-only: 0.0.1
+ react: 18.3.1
+ use-sync-external-store: 1.2.2(react@18.3.1)
+
+ tabbable@6.2.0: {}
+
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
tslib@2.6.3: {}
+ type-fest@4.25.0: {}
+
ufo@1.5.4: {}
undici-types@6.19.6: {}
@@ -2136,6 +2513,42 @@ snapshots:
pathe: 1.1.2
ufo: 1.5.4
+ use-callback-ref@1.3.2(@types/react@18.3.3)(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+ tslib: 2.6.3
+ optionalDependencies:
+ '@types/react': 18.3.3
+
+ use-composed-ref@1.3.0(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+
+ use-isomorphic-layout-effect@1.1.2(@types/react@18.3.3)(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.3
+
+ use-latest@1.2.1(@types/react@18.3.3)(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+ use-isomorphic-layout-effect: 1.1.2(@types/react@18.3.3)(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.3
+
+ use-sidecar@1.1.2(@types/react@18.3.3)(react@18.3.1):
+ dependencies:
+ detect-node-es: 1.1.0
+ react: 18.3.1
+ tslib: 2.6.3
+ optionalDependencies:
+ '@types/react': 18.3.3
+
+ use-sync-external-store@1.2.2(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+
vite@5.4.1(@types/node@22.4.0):
dependencies:
esbuild: 0.21.5
@@ -2192,3 +2605,10 @@ snapshots:
stacktracey: 2.1.8
zod@3.23.8: {}
+
+ zustand@4.5.5(@types/react@18.3.3)(react@18.3.1):
+ dependencies:
+ use-sync-external-store: 1.2.2(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.3
+ react: 18.3.1
diff --git a/schema.ts b/schema.ts
index e521a85..867fd0e 100644
--- a/schema.ts
+++ b/schema.ts
@@ -5,6 +5,8 @@ export const madamis = sqliteTable("Madamis", {
id: integer("id", { mode: "number" }).primaryKey({ autoIncrement: true }),
title: text("title").notNull(),
link: text("link").notNull(),
+ player: integer("player").notNull(),
+ gmRequired: integer("gmRequired").notNull(),
});
export const madamisRelations = relations(madamis, ({ many }) => ({
diff --git a/src/api.ts b/src/api.ts
index 017d147..6d3c1fe 100644
--- a/src/api.ts
+++ b/src/api.ts
@@ -1,12 +1,9 @@
-import { drizzle } from "drizzle-orm/d1";
import { Hono } from "hono";
-import { users } from "../schema";
+import { userApp } from "./apis/user";
+import { madamisApp } from "./apis/madamis";
export const api = new Hono<{ Bindings: Env }>();
-api.get("users/", async (c) => {
- const db = drizzle(c.env.DB);
+const app = api.route("/user", userApp).route("/madamis", madamisApp);
- const result = await db.select().from(users).all();
- return c.json(result);
-});
+export type AppType = typeof app;
diff --git a/src/apis/madamis.ts b/src/apis/madamis.ts
new file mode 100644
index 0000000..e219cec
--- /dev/null
+++ b/src/apis/madamis.ts
@@ -0,0 +1,52 @@
+import { drizzle } from "drizzle-orm/d1";
+import { Hono } from "hono";
+import { madamis } from "../../schema";
+import { z } from "zod";
+import { zValidator } from "@hono/zod-validator";
+import { eq } from "drizzle-orm";
+
+const madamisPostSchema = z.object({
+ title: z.string().min(1),
+ link: z.string().url(),
+ player: z.number().int().min(1).max(6),
+ gmRequired: z.boolean().transform((b) => Number(b)),
+});
+
+const madamisPutSchema = madamisPostSchema.extend({
+ id: z.number().int(),
+});
+
+const madamisApi = new Hono<{ Bindings: Env }>();
+
+export const madamisApp = madamisApi
+ .get("/", async (c) => {
+ const db = drizzle(c.env.DB);
+
+ const result = await db.select().from(madamis);
+ return c.json(result);
+ })
+ .post("/", zValidator("json", madamisPostSchema), async (c) => {
+ const db = drizzle(c.env.DB);
+ const body = c.req.valid("json");
+
+ const [result] = await db.insert(madamis).values(body).returning();
+ return c.json(result);
+ })
+ .put("/", zValidator("json", madamisPutSchema), async (c) => {
+ const db = drizzle(c.env.DB);
+ const body = c.req.valid("json");
+
+ const [result] = await db
+ .update(madamis)
+ .set(body)
+ .where(eq(madamis.id, body.id))
+ .returning();
+ return c.json(result);
+ })
+ .delete("/:id", async (c) => {
+ const db = drizzle(c.env.DB);
+ const id = c.req.param("id");
+
+ await db.delete(madamis).where(eq(madamis.id, parseInt(id)));
+ return new Response(null, { status: 204 });
+ });
diff --git a/src/apis/user.ts b/src/apis/user.ts
new file mode 100644
index 0000000..9cf3469
--- /dev/null
+++ b/src/apis/user.ts
@@ -0,0 +1,12 @@
+import { drizzle } from "drizzle-orm/d1";
+import { Hono } from "hono";
+import { users } from "../../schema";
+
+const userApi = new Hono<{ Bindings: Env }>();
+
+export const userApp = userApi.get("/", async (c) => {
+ const db = drizzle(c.env.DB);
+
+ const result = await db.select().from(users).all();
+ return c.json(result);
+});
diff --git a/src/client.tsx b/src/client.tsx
index 7a2c094..8fee3af 100644
--- a/src/client.tsx
+++ b/src/client.tsx
@@ -1,13 +1,24 @@
import { createRoot } from "react-dom/client";
-import { Component } from "./component";
-const App = () => {
+import "@mantine/core/styles.css";
+import { createTheme, MantineProvider } from "@mantine/core";
+import { App } from "./pages/App";
+
+const theme = createTheme({
+ fontFamily: `"Yusei Magic", sans-serif`,
+ headings: { fontFamily: `"Yusei Magic", sans-serif` },
+ primaryColor: "lime",
+});
+
+const Index = () => {
return (
<>
- Hello,