mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-08-28 05:25:33 +00:00
Merge branch 'new-ui' of https://github.com/Dhravya/supermemory into new-ui
This commit is contained in:
commit
f5887dbbf9
14 changed files with 946 additions and 164 deletions
|
|
@ -14,17 +14,20 @@
|
|||
"prepare-local-db": "drizzle-kit generate:sqlite --out db/prepare.sql && wrangler d1 execute dev-d1-anycontext --local --file=db/prepare.sql"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"next": "14.1.0",
|
||||
"@radix-ui/react-avatar": "^1.0.4",
|
||||
"@radix-ui/react-dialog": "^1.0.5",
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-popover": "^1.0.7",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.0",
|
||||
"lucide-react": "^0.338.0",
|
||||
"next": "14.1.0",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"tailwind-merge": "^2.2.1",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"vaul": "^0.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudflare/next-on-pages": "1",
|
||||
|
|
|
|||
468
apps/web/pnpm-lock.yaml
generated
468
apps/web/pnpm-lock.yaml
generated
|
|
@ -8,9 +8,15 @@ dependencies:
|
|||
'@radix-ui/react-avatar':
|
||||
specifier: ^1.0.4
|
||||
version: 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-dialog':
|
||||
specifier: ^1.0.5
|
||||
version: 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-icons':
|
||||
specifier: ^1.3.0
|
||||
version: 1.3.0(react@18.2.0)
|
||||
'@radix-ui/react-popover':
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-slot':
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.2(@types/react@18.2.73)(react@18.2.0)
|
||||
|
|
@ -38,6 +44,9 @@ dependencies:
|
|||
tailwindcss-animate:
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7(tailwindcss@3.4.3)
|
||||
vaul:
|
||||
specifier: ^0.9.0
|
||||
version: 0.9.0(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
|
||||
devDependencies:
|
||||
'@cloudflare/next-on-pages':
|
||||
|
|
@ -497,6 +506,34 @@ packages:
|
|||
engines: {node: '>=14'}
|
||||
dev: true
|
||||
|
||||
/@floating-ui/core@1.6.0:
|
||||
resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==}
|
||||
dependencies:
|
||||
'@floating-ui/utils': 0.2.1
|
||||
dev: false
|
||||
|
||||
/@floating-ui/dom@1.6.3:
|
||||
resolution: {integrity: sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==}
|
||||
dependencies:
|
||||
'@floating-ui/core': 1.6.0
|
||||
'@floating-ui/utils': 0.2.1
|
||||
dev: false
|
||||
|
||||
/@floating-ui/react-dom@2.0.8(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.0'
|
||||
react-dom: '>=16.8.0'
|
||||
dependencies:
|
||||
'@floating-ui/dom': 1.6.3
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@floating-ui/utils@0.2.1:
|
||||
resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==}
|
||||
dev: false
|
||||
|
||||
/@humanwhocodes/config-array@0.11.14:
|
||||
resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
|
||||
engines: {node: '>=10.10.0'}
|
||||
|
|
@ -693,6 +730,33 @@ packages:
|
|||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@radix-ui/primitive@1.0.1:
|
||||
resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@types/react': 18.2.73
|
||||
'@types/react-dom': 18.2.23
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-avatar@1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-kVK2K7ZD3wwj3qhle0ElXhOjbezIgyl2hVvgwfIdexL3rN6zJmy5AqqIf+D31lxVppdzV8CjAfZ6PklkmInZLw==}
|
||||
peerDependencies:
|
||||
|
|
@ -745,6 +809,102 @@ packages:
|
|||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/primitive': 1.0.1
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-id': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@types/react': 18.2.73
|
||||
'@types/react-dom': 18.2.23
|
||||
aria-hidden: 1.2.4
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
react-remove-scroll: 2.5.5(@types/react@18.2.73)(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/primitive': 1.0.1
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.73)(react@18.2.0)
|
||||
'@types/react': 18.2.73
|
||||
'@types/react-dom': 18.2.23
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.73)(react@18.2.0):
|
||||
resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@types/react': 18.2.73
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@types/react': 18.2.73
|
||||
'@types/react-dom': 18.2.23
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-icons@1.3.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==}
|
||||
peerDependencies:
|
||||
|
|
@ -753,6 +913,129 @@ packages:
|
|||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-id@1.0.1(@types/react@18.2.73)(react@18.2.0):
|
||||
resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@types/react': 18.2.73
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-popover@1.0.7(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/primitive': 1.0.1
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-id': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@types/react': 18.2.73
|
||||
'@types/react-dom': 18.2.23
|
||||
aria-hidden: 1.2.4
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
react-remove-scroll: 2.5.5(@types/react@18.2.73)(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@floating-ui/react-dom': 2.0.8(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-use-size': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/rect': 1.0.1
|
||||
'@types/react': 18.2.73
|
||||
'@types/react-dom': 18.2.23
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@types/react': 18.2.73
|
||||
'@types/react-dom': 18.2.23
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@types/react': 18.2.73
|
||||
'@types/react-dom': 18.2.23
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==}
|
||||
peerDependencies:
|
||||
|
|
@ -803,6 +1086,36 @@ packages:
|
|||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.73)(react@18.2.0):
|
||||
resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@types/react': 18.2.73
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.73)(react@18.2.0):
|
||||
resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@types/react': 18.2.73
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.73)(react@18.2.0):
|
||||
resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==}
|
||||
peerDependencies:
|
||||
|
|
@ -817,6 +1130,42 @@ packages:
|
|||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-rect@1.0.1(@types/react@18.2.73)(react@18.2.0):
|
||||
resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/rect': 1.0.1
|
||||
'@types/react': 18.2.73
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-size@1.0.1(@types/react@18.2.73)(react@18.2.0):
|
||||
resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.73)(react@18.2.0)
|
||||
'@types/react': 18.2.73
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/rect@1.0.1:
|
||||
resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
dev: false
|
||||
|
||||
/@rollup/pluginutils@4.2.1:
|
||||
resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
|
||||
engines: {node: '>= 8.0.0'}
|
||||
|
|
@ -1280,6 +1629,13 @@ packages:
|
|||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
dev: true
|
||||
|
||||
/aria-hidden@1.2.4:
|
||||
resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/aria-query@5.3.0:
|
||||
resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==}
|
||||
dependencies:
|
||||
|
|
@ -1812,6 +2168,10 @@ packages:
|
|||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/detect-node-es@1.1.0:
|
||||
resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
|
||||
dev: false
|
||||
|
||||
/didyoumean@1.2.2:
|
||||
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
|
||||
|
||||
|
|
@ -2982,6 +3342,11 @@ packages:
|
|||
hasown: 2.0.2
|
||||
dev: true
|
||||
|
||||
/get-nonce@1.0.1:
|
||||
resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/get-source@2.0.12:
|
||||
resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==}
|
||||
dependencies:
|
||||
|
|
@ -3225,6 +3590,12 @@ packages:
|
|||
side-channel: 1.0.6
|
||||
dev: true
|
||||
|
||||
/invariant@2.2.4:
|
||||
resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
dev: false
|
||||
|
||||
/is-array-buffer@3.0.4:
|
||||
resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
|
@ -4248,6 +4619,58 @@ packages:
|
|||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||
dev: true
|
||||
|
||||
/react-remove-scroll-bar@2.3.6(@types/react@18.2.73)(react@18.2.0):
|
||||
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
|
||||
dependencies:
|
||||
'@types/react': 18.2.73
|
||||
react: 18.2.0
|
||||
react-style-singleton: 2.2.1(@types/react@18.2.73)(react@18.2.0)
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/react-remove-scroll@2.5.5(@types/react@18.2.73)(react@18.2.0):
|
||||
resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==}
|
||||
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
|
||||
dependencies:
|
||||
'@types/react': 18.2.73
|
||||
react: 18.2.0
|
||||
react-remove-scroll-bar: 2.3.6(@types/react@18.2.73)(react@18.2.0)
|
||||
react-style-singleton: 2.2.1(@types/react@18.2.73)(react@18.2.0)
|
||||
tslib: 2.6.2
|
||||
use-callback-ref: 1.3.2(@types/react@18.2.73)(react@18.2.0)
|
||||
use-sidecar: 1.1.2(@types/react@18.2.73)(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/react-style-singleton@2.2.1(@types/react@18.2.73)(react@18.2.0):
|
||||
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
|
||||
dependencies:
|
||||
'@types/react': 18.2.73
|
||||
get-nonce: 1.0.1
|
||||
invariant: 2.2.4
|
||||
react: 18.2.0
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/react@18.2.0:
|
||||
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
|
@ -5028,6 +5451,37 @@ packages:
|
|||
punycode: 2.3.1
|
||||
dev: true
|
||||
|
||||
/use-callback-ref@1.3.2(@types/react@18.2.73)(react@18.2.0):
|
||||
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
|
||||
dependencies:
|
||||
'@types/react': 18.2.73
|
||||
react: 18.2.0
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/use-sidecar@1.1.2(@types/react@18.2.73)(react@18.2.0):
|
||||
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
|
||||
dependencies:
|
||||
'@types/react': 18.2.73
|
||||
detect-node-es: 1.1.0
|
||||
react: 18.2.0
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
|
|
@ -5041,6 +5495,20 @@ packages:
|
|||
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
||||
dev: true
|
||||
|
||||
/vaul@0.9.0(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-bZSySGbAHiTXmZychprnX/dE0EsSige88xtyyL3/MCRbrFotRPQZo7UdydGXZWw+CKbNOw5Ow8gwAo93/nB/Cg==}
|
||||
peerDependencies:
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
dependencies:
|
||||
'@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
- '@types/react-dom'
|
||||
dev: false
|
||||
|
||||
/vercel@33.6.2:
|
||||
resolution: {integrity: sha512-9tpC+wAtGSKiZf1TPjXZK6ntQDK0IZPd5xl99Ka91bcNQS9Z/8jJ/IKmTbgKw80z7i769ozMPtKj3/jTRnWuhw==}
|
||||
engines: {node: '>= 16'}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
}
|
||||
|
||||
body {
|
||||
@apply bg-rgray-1 text-rgray-11;
|
||||
@apply bg-rgray-2 text-rgray-11;
|
||||
/* color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
|
|
@ -30,6 +30,10 @@ body {
|
|||
rgb(var(--background-start-rgb)); */
|
||||
}
|
||||
|
||||
[vaul-drawer-wrapper] {
|
||||
@apply bg-rgray-1;
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.text-balance {
|
||||
text-wrap: balance;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,11 @@ export default function RootLayout({
|
|||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={roboto.className}>{children}</body>
|
||||
<body className={roboto.className}>
|
||||
<div vaul-drawer-wrapper="" className="min-w-screen overflow-x-hidden">
|
||||
{children}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import Sidebar from "@/components/Sidebar";
|
||||
import Sidebar from "@/components/Sidebar/index";
|
||||
|
||||
export default async function Home() {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,145 +0,0 @@
|
|||
"use client";
|
||||
import { StoredContent } from "@/server/db/schema";
|
||||
import {
|
||||
Plus,
|
||||
MoreHorizontal,
|
||||
ArrowUpRight,
|
||||
Edit3,
|
||||
Trash2,
|
||||
} from "lucide-react";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "./ui/dropdown-menu";
|
||||
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
|
||||
export default function Sidebar() {
|
||||
const websties: StoredContent[] = [
|
||||
{
|
||||
id: 1,
|
||||
content: "",
|
||||
title: "Visual Studio Code",
|
||||
url: "https://code.visualstudio.com",
|
||||
description: "",
|
||||
image: "https://code.visualstudio.com/favicon.ico",
|
||||
baseUrl: "https://code.visualstudio.com",
|
||||
savedAt: new Date(),
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
content: "",
|
||||
title: "yxshv/vscode: An unofficial remake of vscode's landing page",
|
||||
url: "https://github.com/yxshv/vscode",
|
||||
description: "",
|
||||
image: "https://github.com/favicon.ico",
|
||||
baseUrl: "https://github.com",
|
||||
savedAt: new Date(),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<aside className="bg-rgray-3 flex h-screen w-[25%] flex-col items-start justify-between py-5 pb-[50vh] font-light">
|
||||
<div className="flex items-center justify-center gap-1 px-5 text-xl font-normal">
|
||||
<img src="/brain.png" alt="logo" className="h-10 w-10" />
|
||||
SuperMemory
|
||||
</div>
|
||||
<div className="flex w-full flex-col items-start justify-center p-2">
|
||||
<h1 className="mb-1 flex w-full items-center justify-center px-3 font-normal">
|
||||
Websites
|
||||
<button className="ml-auto ">
|
||||
<Plus className="h-4 w-4 min-w-4" />
|
||||
</button>
|
||||
</h1>
|
||||
{websties.map((item) => (
|
||||
<ListItem key={item.id} item={item} />
|
||||
))}
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
export const ListItem: React.FC<{ item: StoredContent }> = ({ item }) => {
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
const editInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (isEditing) {
|
||||
setTimeout(() => {
|
||||
editInputRef.current?.focus();
|
||||
}, 500);
|
||||
}
|
||||
}, [isEditing]);
|
||||
|
||||
return (
|
||||
<div className="hover:bg-rgray-5 focus-within:bg-rgray-5 flex w-full items-center rounded-full py-1 pl-3 pr-2 transition [&:hover>a>[data-upright-icon]]:block [&:hover>a>img]:hidden [&:hover>button]:opacity-100">
|
||||
<a
|
||||
href={item.url}
|
||||
target="_blank"
|
||||
onClick={(e) => isEditing && e.preventDefault()}
|
||||
className="flex w-[90%] items-center gap-2 focus:outline-none"
|
||||
>
|
||||
{isEditing ? (
|
||||
<Edit3 className="h-4 w-4" strokeWidth={1.5} />
|
||||
) : (
|
||||
<>
|
||||
<img
|
||||
src={item.image ?? "/brain.png"}
|
||||
alt={item.title ?? "Untitiled website"}
|
||||
className="h-4 w-4"
|
||||
/>
|
||||
<ArrowUpRight
|
||||
data-upright-icon
|
||||
className="hidden h-4 w-4 min-w-4 scale-125"
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{isEditing ? (
|
||||
<input
|
||||
ref={editInputRef}
|
||||
autoFocus
|
||||
className="text-rgray-12 w-full bg-transparent focus:outline-none"
|
||||
placeholder={item.title ?? "Untitled website"}
|
||||
onBlur={(e) => setIsEditing(false)}
|
||||
onKeyDown={(e) => e.key === "Escape" && setIsEditing(false)}
|
||||
/>
|
||||
) : (
|
||||
<span className="w-full truncate text-nowrap">
|
||||
{item.title ?? "Untitled website"}
|
||||
</span>
|
||||
)}
|
||||
</a>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<button className="ml-auto w-4 min-w-4 rounded-[0.15rem] opacity-0 focus:opacity-100 focus:outline-none">
|
||||
<MoreHorizontal className="h-4 w-4 min-w-4" />
|
||||
</button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-5">
|
||||
<DropdownMenuItem onClick={() => window.open(item.url)}>
|
||||
<ArrowUpRight
|
||||
className="mr-2 h-4 w-4 scale-125"
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
Open
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={(e) => {
|
||||
setIsEditing(true);
|
||||
}}
|
||||
>
|
||||
<Edit3 className="mr-2 h-4 w-4 " strokeWidth={1.5} />
|
||||
Edit
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="focus:bg-red-100 focus:text-red-400 dark:focus:bg-red-100/10">
|
||||
<Trash2 className="mr-2 h-4 w-4 " strokeWidth={1.5} />
|
||||
Delete
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
189
apps/web/src/components/Sidebar/PagesItem.tsx
Normal file
189
apps/web/src/components/Sidebar/PagesItem.tsx
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
"use client";
|
||||
import { cleanUrl } from "@/lib/utils";
|
||||
import { StoredContent } from "@/server/db/schema";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
} from "../ui/dropdown-menu";
|
||||
import { Label } from "../ui/label";
|
||||
import {
|
||||
ArrowUpRight,
|
||||
MoreHorizontal,
|
||||
Edit3,
|
||||
Trash2,
|
||||
Save,
|
||||
ChevronRight,
|
||||
Plus,
|
||||
} from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Drawer,
|
||||
DrawerContent,
|
||||
DrawerHeader,
|
||||
DrawerTitle,
|
||||
DrawerDescription,
|
||||
DrawerFooter,
|
||||
DrawerClose,
|
||||
} from "../ui/drawer";
|
||||
import { Input } from "../ui/input";
|
||||
import { Textarea } from "../ui/textarea";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
|
||||
|
||||
export const PageItem: React.FC<{ item: StoredContent }> = ({ item }) => {
|
||||
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
||||
const [isEditDrawerOpen, setIsEditDrawerOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="hover:bg-rgray-5 focus-within:bg-rgray-5 flex w-full items-center rounded-full py-1 pl-3 pr-2 transition [&:hover>a>div>[data-upright-icon]]:scale-125 [&:hover>a>div>[data-upright-icon]]:opacity-100 [&:hover>a>div>[data-upright-icon]]:delay-150 [&:hover>a>div>img]:scale-75 [&:hover>a>div>img]:opacity-0 [&:hover>a>div>img]:delay-0 [&:hover>button]:opacity-100">
|
||||
<a
|
||||
href={item.url}
|
||||
target="_blank"
|
||||
className="flex w-[90%] items-center gap-2 focus-visible:outline-none"
|
||||
>
|
||||
<div className="relative h-4 min-w-4">
|
||||
<img
|
||||
src={item.image ?? "/brain.png"}
|
||||
alt={item.title ?? "Untitiled website"}
|
||||
className="z-1 h-4 w-4 transition-[transform,opacity] delay-150 duration-150"
|
||||
/>
|
||||
<ArrowUpRight
|
||||
data-upright-icon
|
||||
className="absolute left-1/2 top-1/2 z-[2] h-4 w-4 min-w-4 -translate-x-1/2 -translate-y-1/2 scale-75 opacity-0 transition-[transform,opacity] duration-150"
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<span className="w-full truncate text-nowrap">
|
||||
{item.title ?? "Untitled website"}
|
||||
</span>
|
||||
</a>
|
||||
<DropdownMenu open={isDropdownOpen} onOpenChange={setIsDropdownOpen}>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<button className="ml-auto w-4 min-w-4 rounded-[0.15rem] opacity-0 focus-visible:opacity-100 focus-visible:outline-none">
|
||||
<MoreHorizontal className="h-4 w-4 min-w-4" />
|
||||
</button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-5">
|
||||
<DropdownMenuItem onClick={() => window.open(item.url)}>
|
||||
<ArrowUpRight
|
||||
className="mr-2 h-4 w-4 scale-125"
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
Open
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
setIsDropdownOpen(false);
|
||||
setIsEditDrawerOpen(true);
|
||||
}}
|
||||
>
|
||||
<Edit3 className="mr-2 h-4 w-4" strokeWidth={1.5} />
|
||||
Edit
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="focus-visible:bg-red-100 focus-visible:text-red-400 dark:focus-visible:bg-red-100/10">
|
||||
<Trash2 className="mr-2 h-4 w-4" strokeWidth={1.5} />
|
||||
Delete
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<Drawer
|
||||
shouldScaleBackground
|
||||
open={isEditDrawerOpen}
|
||||
onOpenChange={setIsEditDrawerOpen}
|
||||
>
|
||||
<DrawerContent className="pb-10 lg:px-[25vw]">
|
||||
<DrawerHeader className="relative mt-10 px-0">
|
||||
<DrawerTitle className=" flex w-full justify-between">
|
||||
Edit Page Details
|
||||
</DrawerTitle>
|
||||
<DrawerDescription>Change the page details</DrawerDescription>
|
||||
<a
|
||||
target="_blank"
|
||||
href={item.url}
|
||||
className="text-rgray-11/90 bg-rgray-3 text-md absolute right-0 top-0 flex w-min translate-y-1/2 items-center justify-center gap-1 rounded-full px-5 py-1"
|
||||
>
|
||||
<img src={item.image ?? "/brain.png"} className="h-4 w-4" />
|
||||
{cleanUrl(item.url)}
|
||||
</a>
|
||||
</DrawerHeader>
|
||||
|
||||
<div className="mt-5">
|
||||
<Label>Title</Label>
|
||||
<Input
|
||||
className=""
|
||||
required
|
||||
value={item.title ?? ""}
|
||||
placeholder={item.title ?? "Enter the title for the page"}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<Label>Additional Context</Label>
|
||||
<Textarea
|
||||
className=""
|
||||
value={item.content ?? ""}
|
||||
placeholder={"Enter additional context for this page"}
|
||||
/>
|
||||
</div>
|
||||
<DrawerFooter className="flex flex-row-reverse items-center justify-end px-0 pt-5">
|
||||
<DrawerClose className="flex items-center justify-center rounded-md px-3 py-2 ring-2 ring-transparent transition hover:bg-blue-100 hover:text-blue-400 focus-visible:bg-blue-100 focus-visible:text-blue-400 focus-visible:outline-none focus-visible:ring-blue-200 dark:hover:bg-blue-100/10 dark:focus-visible:bg-blue-100/10 dark:focus-visible:ring-blue-200/30">
|
||||
<Save className="mr-2 h-4 w-4 " strokeWidth={1.5} />
|
||||
Save
|
||||
</DrawerClose>
|
||||
<DrawerClose className="hover:bg-rgray-3 focus-visible:bg-rgray-4 focus-visible:ring-rgray-7 flex items-center justify-center rounded-md px-3 py-2 ring-2 ring-transparent transition focus-visible:outline-none">
|
||||
Cancel
|
||||
</DrawerClose>
|
||||
<DrawerClose className="mr-auto flex items-center justify-center rounded-md bg-red-100 px-3 py-2 text-red-400 ring-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-red-200 dark:bg-red-100/10 dark:focus-visible:ring-red-200/30">
|
||||
<Trash2 className="mr-2 h-4 w-4 " strokeWidth={1.5} />
|
||||
Delete
|
||||
</DrawerClose>
|
||||
</DrawerFooter>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const AddNewPagePopover: React.FC<{
|
||||
addNewUrl?: (url: string) => Promise<void>;
|
||||
}> = ({ addNewUrl }) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [url, setUrl] = useState("");
|
||||
|
||||
return (
|
||||
<Popover open={isOpen} onOpenChange={setIsOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<button className="focus-visible:ring-rgray-7 ring-offset-rgray-3 ml-auto rounded-sm ring-2 ring-transparent ring-offset-2 focus-visible:outline-none">
|
||||
<Plus className="h-4 w-4 min-w-4" />
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="start" side="top">
|
||||
<h1 className="mb-2 flex items-center justify-between ">
|
||||
Add a new page
|
||||
<button
|
||||
onClick={() => {
|
||||
setIsOpen(false);
|
||||
addNewUrl?.(url);
|
||||
}}
|
||||
className="hover:bg-rgray-3 focus-visible:bg-rgray-4 focus-visible:ring-rgray-7 ring-offset-rgray-3 rounded-sm ring-2 ring-transparent ring-offset-2 transition focus-visible:outline-none"
|
||||
>
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
</button>
|
||||
</h1>
|
||||
<Input
|
||||
className="w-full"
|
||||
autoFocus
|
||||
onChange={(e) => setUrl(e.target.value)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") {
|
||||
setIsOpen(false);
|
||||
addNewUrl?.(url);
|
||||
}
|
||||
}}
|
||||
placeholder="Enter the URL of the page"
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
46
apps/web/src/components/Sidebar/index.tsx
Normal file
46
apps/web/src/components/Sidebar/index.tsx
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
"use server";
|
||||
import { StoredContent } from "@/server/db/schema";
|
||||
import { AddNewPagePopover, PageItem } from "./PagesItem";
|
||||
|
||||
export default async function Sidebar() {
|
||||
const pages: StoredContent[] = [
|
||||
{
|
||||
id: 1,
|
||||
content: "",
|
||||
title: "Visual Studio Code",
|
||||
url: "https://code.visualstudio.com",
|
||||
description: "",
|
||||
image: "https://code.visualstudio.com/favicon.ico",
|
||||
baseUrl: "https://code.visualstudio.com",
|
||||
savedAt: new Date(),
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
content: "",
|
||||
title: "yxshv/vscode: An unofficial remake of vscode's landing page",
|
||||
url: "https://github.com/yxshv/vscode",
|
||||
description: "",
|
||||
image: "https://github.com/favicon.ico",
|
||||
baseUrl: "https://github.com",
|
||||
savedAt: new Date(),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<aside className="bg-rgray-3 flex h-screen w-[25%] flex-col items-start justify-between py-5 pb-[50vh] font-light">
|
||||
<div className="flex items-center justify-center gap-1 px-5 text-xl font-normal">
|
||||
<img src="/brain.png" alt="logo" className="h-10 w-10" />
|
||||
SuperMemory
|
||||
</div>
|
||||
<div className="flex w-full flex-col items-start justify-center p-2">
|
||||
<h1 className="mb-1 flex w-full items-center justify-center px-3 font-normal">
|
||||
Pages
|
||||
<AddNewPagePopover />
|
||||
</h1>
|
||||
{pages.map((item) => (
|
||||
<PageItem key={item.id} item={item} />
|
||||
))}
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
118
apps/web/src/components/ui/drawer.tsx
Normal file
118
apps/web/src/components/ui/drawer.tsx
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import { Drawer as DrawerPrimitive } from "vaul";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Drawer = ({
|
||||
shouldScaleBackground = true,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
|
||||
<DrawerPrimitive.Root
|
||||
shouldScaleBackground={shouldScaleBackground}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
Drawer.displayName = "Drawer";
|
||||
|
||||
const DrawerTrigger = DrawerPrimitive.Trigger;
|
||||
|
||||
const DrawerPortal = DrawerPrimitive.Portal;
|
||||
|
||||
const DrawerClose = DrawerPrimitive.Close;
|
||||
|
||||
const DrawerOverlay = React.forwardRef<
|
||||
React.ElementRef<typeof DrawerPrimitive.Overlay>,
|
||||
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DrawerPrimitive.Overlay
|
||||
ref={ref}
|
||||
className={cn("fixed inset-0 z-50 bg-black/80", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName;
|
||||
|
||||
const DrawerContent = React.forwardRef<
|
||||
React.ElementRef<typeof DrawerPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<DrawerPortal>
|
||||
<DrawerOverlay />
|
||||
<DrawerPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"border-rgray-6 bg-rgray-2 fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<div className="bg-rgray-4 mx-auto mt-4 h-2 w-[100px] rounded-full " />
|
||||
{children}
|
||||
</DrawerPrimitive.Content>
|
||||
</DrawerPortal>
|
||||
));
|
||||
DrawerContent.displayName = "DrawerContent";
|
||||
|
||||
const DrawerHeader = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div
|
||||
className={cn("grid gap-1.5 p-4 text-center sm:text-left", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
DrawerHeader.displayName = "DrawerHeader";
|
||||
|
||||
const DrawerFooter = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div
|
||||
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
DrawerFooter.displayName = "DrawerFooter";
|
||||
|
||||
const DrawerTitle = React.forwardRef<
|
||||
React.ElementRef<typeof DrawerPrimitive.Title>,
|
||||
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DrawerPrimitive.Title
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"text-rgray-12 text-xl font-medium leading-none tracking-tight",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DrawerTitle.displayName = DrawerPrimitive.Title.displayName;
|
||||
|
||||
const DrawerDescription = React.forwardRef<
|
||||
React.ElementRef<typeof DrawerPrimitive.Description>,
|
||||
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DrawerPrimitive.Description
|
||||
ref={ref}
|
||||
className={cn("text-rgray-11 text-md", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DrawerDescription.displayName = DrawerPrimitive.Description.displayName;
|
||||
|
||||
export {
|
||||
Drawer,
|
||||
DrawerPortal,
|
||||
DrawerOverlay,
|
||||
DrawerTrigger,
|
||||
DrawerClose,
|
||||
DrawerContent,
|
||||
DrawerHeader,
|
||||
DrawerFooter,
|
||||
DrawerTitle,
|
||||
DrawerDescription,
|
||||
};
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import * as React from "react"
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export interface InputProps
|
||||
extends React.InputHTMLAttributes<HTMLInputElement> {}
|
||||
|
|
@ -11,15 +11,15 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|||
<input
|
||||
type={type}
|
||||
className={cn(
|
||||
"flex h-10 w-full rounded-md border border-gray-200 bg-white px-3 py-2 text-sm ring-offset-white file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gray-950 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-800 dark:bg-gray-950 dark:ring-offset-gray-950 dark:placeholder:text-gray-400 dark:focus-visible:ring-gray-300",
|
||||
className
|
||||
"border-rgray-6 text-rgray-12 ring-offset-rgray-2 placeholder:text-rgray-11 focus-visible:ring-rgray-7 flex h-10 w-full rounded-md border bg-transparent px-3 py-2 text-sm transition file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ",
|
||||
className,
|
||||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
)
|
||||
Input.displayName = "Input"
|
||||
);
|
||||
},
|
||||
);
|
||||
Input.displayName = "Input";
|
||||
|
||||
export { Input }
|
||||
export { Input };
|
||||
|
|
|
|||
31
apps/web/src/components/ui/popover.tsx
Normal file
31
apps/web/src/components/ui/popover.tsx
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Popover = PopoverPrimitive.Root;
|
||||
|
||||
const PopoverTrigger = PopoverPrimitive.Trigger;
|
||||
|
||||
const PopoverContent = React.forwardRef<
|
||||
React.ElementRef<typeof PopoverPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
|
||||
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
|
||||
<PopoverPrimitive.Portal>
|
||||
<PopoverPrimitive.Content
|
||||
ref={ref}
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"border-rgray-6 bg-rgray-3 text-rgray-11 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 rounded-md border p-4 shadow-md outline-none",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</PopoverPrimitive.Portal>
|
||||
));
|
||||
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
||||
|
||||
export { Popover, PopoverTrigger, PopoverContent };
|
||||
24
apps/web/src/components/ui/textarea.tsx
Normal file
24
apps/web/src/components/ui/textarea.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export interface TextareaProps
|
||||
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
|
||||
|
||||
const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
||||
({ className, ...props }, ref) => {
|
||||
return (
|
||||
<textarea
|
||||
className={cn(
|
||||
"border-rgray-6 ring-offset-rgray-2 placeholder:text-rgray-11 focus-visible:ring-rgray-7 flex min-h-[80px] w-full rounded-md border bg-transparent px-3 py-2 text-sm transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className,
|
||||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
Textarea.displayName = "Textarea";
|
||||
|
||||
export { Textarea };
|
||||
|
|
@ -1,6 +1,19 @@
|
|||
import { type ClassValue, clsx } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
"use client";
|
||||
import { type ClassValue, clsx } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
|
||||
// removes http(s?):// and / from the url
|
||||
export function cleanUrl(url: string) {
|
||||
if (url.endsWith("/")) {
|
||||
url = url.slice(0, -1);
|
||||
}
|
||||
return url.startsWith("https://")
|
||||
? url.slice(8)
|
||||
: url.startsWith("http://")
|
||||
? url.slice(7)
|
||||
: url;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,32 @@ const config: Config = {
|
|||
],
|
||||
theme: {
|
||||
extend: {
|
||||
keyframes: {
|
||||
"scale-in": {
|
||||
"0%": {
|
||||
transform: "scale(0)",
|
||||
transformOrigin: "var(--radix-popover-content-transform-origin)",
|
||||
},
|
||||
"100%": {
|
||||
transform: "scale(1)",
|
||||
transformOrigin: "var(--radix-popover-content-transform-origin)",
|
||||
},
|
||||
},
|
||||
"scale-out": {
|
||||
"0%": {
|
||||
transform: "scale(1)",
|
||||
transformOrigin: "var(--radix-popover-content-transform-origin)",
|
||||
},
|
||||
"100%": {
|
||||
transform: "scale(0)",
|
||||
transformOrigin: "var(--radix-popover-content-transform-origin)",
|
||||
},
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
"scale-in": "scale-in 0.2s cubic-bezier(0.16, 1, 0.3, 1)",
|
||||
"scale-out": "scale-out 0.2s cubic-bezier(0.16, 1, 0.3, 1)",
|
||||
},
|
||||
backgroundImage: {
|
||||
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
|
||||
"gradient-conic":
|
||||
|
|
@ -31,6 +57,7 @@ const config: Config = {
|
|||
},
|
||||
},
|
||||
},
|
||||
darkMode: "class",
|
||||
plugins: [require("tailwindcss-animate")],
|
||||
};
|
||||
export default config;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue