init: 0.0.6
next: upload
This commit is contained in:
@ -10,10 +10,10 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.4",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"tailwindcss": "^4.1.4"
|
||||
"react-jss": "^10.10.0",
|
||||
"zustand": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.22.0",
|
||||
|
494
frontend/pnpm-lock.yaml
generated
494
frontend/pnpm-lock.yaml
generated
@ -8,18 +8,18 @@ importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
'@tailwindcss/vite':
|
||||
specifier: ^4.1.4
|
||||
version: 4.1.4(vite@6.3.3(jiti@2.4.2)(lightningcss@1.29.2))
|
||||
react:
|
||||
specifier: ^19.0.0
|
||||
version: 19.1.0
|
||||
react-dom:
|
||||
specifier: ^19.0.0
|
||||
version: 19.1.0(react@19.1.0)
|
||||
tailwindcss:
|
||||
specifier: ^4.1.4
|
||||
version: 4.1.4
|
||||
react-jss:
|
||||
specifier: ^10.10.0
|
||||
version: 10.10.0(react@19.1.0)
|
||||
zustand:
|
||||
specifier: ^5.0.3
|
||||
version: 5.0.3(@types/react@19.1.2)(react@19.1.0)
|
||||
devDependencies:
|
||||
'@eslint/js':
|
||||
specifier: ^9.22.0
|
||||
@ -128,6 +128,10 @@ packages:
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/runtime@7.27.0':
|
||||
resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/template@7.27.0':
|
||||
resolution: {integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@ -140,6 +144,12 @@ packages:
|
||||
resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@emotion/is-prop-valid@0.7.3':
|
||||
resolution: {integrity: sha512-uxJqm/sqwXw3YPA5GXX365OBcJGFtxUVkB6WyezqFHlNe9jqUWH5ur2O2M8dGBz61kn1g3ZBlzUunFQXQIClhA==}
|
||||
|
||||
'@emotion/memoize@0.7.1':
|
||||
resolution: {integrity: sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg==}
|
||||
|
||||
'@esbuild/aix-ppc64@0.25.3':
|
||||
resolution: {integrity: sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==}
|
||||
engines: {node: '>=18'}
|
||||
@ -489,100 +499,6 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@tailwindcss/node@4.1.4':
|
||||
resolution: {integrity: sha512-MT5118zaiO6x6hNA04OWInuAiP1YISXql8Z+/Y8iisV5nuhM8VXlyhRuqc2PEviPszcXI66W44bCIk500Oolhw==}
|
||||
|
||||
'@tailwindcss/oxide-android-arm64@4.1.4':
|
||||
resolution: {integrity: sha512-xMMAe/SaCN/vHfQYui3fqaBDEXMu22BVwQ33veLc8ep+DNy7CWN52L+TTG9y1K397w9nkzv+Mw+mZWISiqhmlA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@tailwindcss/oxide-darwin-arm64@4.1.4':
|
||||
resolution: {integrity: sha512-JGRj0SYFuDuAGilWFBlshcexev2hOKfNkoX+0QTksKYq2zgF9VY/vVMq9m8IObYnLna0Xlg+ytCi2FN2rOL0Sg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@tailwindcss/oxide-darwin-x64@4.1.4':
|
||||
resolution: {integrity: sha512-sdDeLNvs3cYeWsEJ4H1DvjOzaGios4QbBTNLVLVs0XQ0V95bffT3+scptzYGPMjm7xv4+qMhCDrkHwhnUySEzA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@tailwindcss/oxide-freebsd-x64@4.1.4':
|
||||
resolution: {integrity: sha512-VHxAqxqdghM83HslPhRsNhHo91McsxRJaEnShJOMu8mHmEj9Ig7ToHJtDukkuLWLzLboh2XSjq/0zO6wgvykNA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@tailwindcss/oxide-linux-arm-gnueabihf@4.1.4':
|
||||
resolution: {integrity: sha512-OTU/m/eV4gQKxy9r5acuesqaymyeSCnsx1cFto/I1WhPmi5HDxX1nkzb8KYBiwkHIGg7CTfo/AcGzoXAJBxLfg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@tailwindcss/oxide-linux-arm64-gnu@4.1.4':
|
||||
resolution: {integrity: sha512-hKlLNvbmUC6z5g/J4H+Zx7f7w15whSVImokLPmP6ff1QqTVE+TxUM9PGuNsjHvkvlHUtGTdDnOvGNSEUiXI1Ww==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tailwindcss/oxide-linux-arm64-musl@4.1.4':
|
||||
resolution: {integrity: sha512-X3As2xhtgPTY/m5edUtddmZ8rCruvBvtxYLMw9OsZdH01L2gS2icsHRwxdU0dMItNfVmrBezueXZCHxVeeb7Aw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@tailwindcss/oxide-linux-x64-gnu@4.1.4':
|
||||
resolution: {integrity: sha512-2VG4DqhGaDSmYIu6C4ua2vSLXnJsb/C9liej7TuSO04NK+JJJgJucDUgmX6sn7Gw3Cs5ZJ9ZLrnI0QRDOjLfNQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tailwindcss/oxide-linux-x64-musl@4.1.4':
|
||||
resolution: {integrity: sha512-v+mxVgH2kmur/X5Mdrz9m7TsoVjbdYQT0b4Z+dr+I4RvreCNXyCFELZL/DO0M1RsidZTrm6O1eMnV6zlgEzTMQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@tailwindcss/oxide-wasm32-wasi@4.1.4':
|
||||
resolution: {integrity: sha512-2TLe9ir+9esCf6Wm+lLWTMbgklIjiF0pbmDnwmhR9MksVOq+e8aP3TSsXySnBDDvTTVd/vKu1aNttEGj3P6l8Q==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [wasm32]
|
||||
bundledDependencies:
|
||||
- '@napi-rs/wasm-runtime'
|
||||
- '@emnapi/core'
|
||||
- '@emnapi/runtime'
|
||||
- '@tybys/wasm-util'
|
||||
- '@emnapi/wasi-threads'
|
||||
- tslib
|
||||
|
||||
'@tailwindcss/oxide-win32-arm64-msvc@4.1.4':
|
||||
resolution: {integrity: sha512-VlnhfilPlO0ltxW9/BgfLI5547PYzqBMPIzRrk4W7uupgCt8z6Trw/tAj6QUtF2om+1MH281Pg+HHUJoLesmng==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@tailwindcss/oxide-win32-x64-msvc@4.1.4':
|
||||
resolution: {integrity: sha512-+7S63t5zhYjslUGb8NcgLpFXD+Kq1F/zt5Xv5qTv7HaFTG/DHyHD9GA6ieNAxhgyA4IcKa/zy7Xx4Oad2/wuhw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@tailwindcss/oxide@4.1.4':
|
||||
resolution: {integrity: sha512-p5wOpXyOJx7mKh5MXh5oKk+kqcz8T+bA3z/5VWWeQwFrmuBItGwz8Y2CHk/sJ+dNb9B0nYFfn0rj/cKHZyjahQ==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
'@tailwindcss/vite@4.1.4':
|
||||
resolution: {integrity: sha512-4UQeMrONbvrsXKXXp/uxmdEN5JIJ9RkH7YVzs6AMxC/KC1+Np7WZBaNIco7TEjlkthqxZbt8pU/ipD+hKjm80A==}
|
||||
peerDependencies:
|
||||
vite: ^5.2.0 || ^6
|
||||
|
||||
'@types/babel__core@7.20.5':
|
||||
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
|
||||
|
||||
@ -728,6 +644,12 @@ packages:
|
||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
css-jss@10.10.0:
|
||||
resolution: {integrity: sha512-YyMIS/LsSKEGXEaVJdjonWe18p4vXLo8CMA4FrW/kcaEyqdIGKCFXao31gbJddXEdIxSXFFURWrenBJPlKTgAA==}
|
||||
|
||||
css-vendor@2.0.8:
|
||||
resolution: {integrity: sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==}
|
||||
|
||||
csstype@3.1.3:
|
||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||
|
||||
@ -750,10 +672,6 @@ packages:
|
||||
electron-to-chromium@1.5.143:
|
||||
resolution: {integrity: sha512-QqklJMOFBMqe46k8iIOwA9l2hz57V2OKMmP5eSWcUvwx+mASAsbU+wkF1pHjn9ZVSBPrsYWr4/W/95y5SwYg2g==}
|
||||
|
||||
enhanced-resolve@5.18.1:
|
||||
resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
||||
esbuild@0.25.3:
|
||||
resolution: {integrity: sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==}
|
||||
engines: {node: '>=18'}
|
||||
@ -892,9 +810,6 @@ packages:
|
||||
resolution: {integrity: sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
|
||||
graphemer@1.4.0:
|
||||
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
|
||||
|
||||
@ -902,6 +817,12 @@ packages:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
hoist-non-react-statics@3.3.2:
|
||||
resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
|
||||
|
||||
hyphenate-style-name@1.1.0:
|
||||
resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==}
|
||||
|
||||
ignore@5.3.2:
|
||||
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
||||
engines: {node: '>= 4'}
|
||||
@ -922,6 +843,9 @@ packages:
|
||||
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
is-in-browser@1.1.3:
|
||||
resolution: {integrity: sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==}
|
||||
|
||||
is-number@7.0.0:
|
||||
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
|
||||
engines: {node: '>=0.12.0'}
|
||||
@ -959,6 +883,48 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
jss-plugin-camel-case@10.10.0:
|
||||
resolution: {integrity: sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==}
|
||||
|
||||
jss-plugin-compose@10.10.0:
|
||||
resolution: {integrity: sha512-F5kgtWpI2XfZ3Z8eP78tZEYFdgTIbpA/TMuX3a8vwrNolYtN1N4qJR/Ob0LAsqIwCMLojtxN7c7Oo/+Vz6THow==}
|
||||
|
||||
jss-plugin-default-unit@10.10.0:
|
||||
resolution: {integrity: sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==}
|
||||
|
||||
jss-plugin-expand@10.10.0:
|
||||
resolution: {integrity: sha512-ymT62W2OyDxBxr7A6JR87vVX9vTq2ep5jZLIdUSusfBIEENLdkkc0lL/Xaq8W9s3opUq7R0sZQpzRWELrfVYzA==}
|
||||
|
||||
jss-plugin-extend@10.10.0:
|
||||
resolution: {integrity: sha512-sKYrcMfr4xxigmIwqTjxNcHwXJIfvhvjTNxF+Tbc1NmNdyspGW47Ey6sGH8BcQ4FFQhLXctpWCQSpDwdNmXSwg==}
|
||||
|
||||
jss-plugin-global@10.10.0:
|
||||
resolution: {integrity: sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==}
|
||||
|
||||
jss-plugin-nested@10.10.0:
|
||||
resolution: {integrity: sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==}
|
||||
|
||||
jss-plugin-props-sort@10.10.0:
|
||||
resolution: {integrity: sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==}
|
||||
|
||||
jss-plugin-rule-value-function@10.10.0:
|
||||
resolution: {integrity: sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==}
|
||||
|
||||
jss-plugin-rule-value-observable@10.10.0:
|
||||
resolution: {integrity: sha512-ZLMaYrR3QE+vD7nl3oNXuj79VZl9Kp8/u6A1IbTPDcuOu8b56cFdWRZNZ0vNr8jHewooEeq2doy8Oxtymr2ZPA==}
|
||||
|
||||
jss-plugin-template@10.10.0:
|
||||
resolution: {integrity: sha512-ocXZBIOJOA+jISPdsgkTs8wwpK6UbsvtZK5JI7VUggTD6LWKbtoxUzadd2TpfF+lEtlhUmMsCkTRNkITdPKa6w==}
|
||||
|
||||
jss-plugin-vendor-prefixer@10.10.0:
|
||||
resolution: {integrity: sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==}
|
||||
|
||||
jss-preset-default@10.10.0:
|
||||
resolution: {integrity: sha512-GL175Wt2FGhjE+f+Y3aWh+JioL06/QWFgZp53CbNNq6ZkVU0TDplD8Bxm9KnkotAYn3FlplNqoW5CjyLXcoJ7Q==}
|
||||
|
||||
jss@10.10.0:
|
||||
resolution: {integrity: sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==}
|
||||
|
||||
keyv@4.5.4:
|
||||
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
||||
|
||||
@ -1041,6 +1007,10 @@ packages:
|
||||
lodash.merge@4.6.2:
|
||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||
|
||||
loose-envify@1.4.0:
|
||||
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
|
||||
hasBin: true
|
||||
|
||||
lru-cache@5.1.1:
|
||||
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
||||
|
||||
@ -1073,6 +1043,10 @@ packages:
|
||||
node-releases@2.0.19:
|
||||
resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==}
|
||||
|
||||
object-assign@4.1.1:
|
||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
optionator@0.9.4:
|
||||
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
@ -1116,6 +1090,9 @@ packages:
|
||||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
||||
prop-types@15.8.1:
|
||||
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
||||
|
||||
punycode@2.3.1:
|
||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||
engines: {node: '>=6'}
|
||||
@ -1123,11 +1100,22 @@ packages:
|
||||
queue-microtask@1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
|
||||
react-display-name@0.2.5:
|
||||
resolution: {integrity: sha512-I+vcaK9t4+kypiSgaiVWAipqHRXYmZIuAiS8vzFvXHHXVigg/sMKwlRgLy6LH2i3rmP+0Vzfl5lFsFRwF1r3pg==}
|
||||
|
||||
react-dom@19.1.0:
|
||||
resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==}
|
||||
peerDependencies:
|
||||
react: ^19.1.0
|
||||
|
||||
react-is@16.13.1:
|
||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||
|
||||
react-jss@10.10.0:
|
||||
resolution: {integrity: sha512-WLiq84UYWqNBF6579/uprcIUnM1TSywYq6AIjKTTTG5ziJl9Uy+pwuvpN3apuyVwflMbD60PraeTKT7uWH9XEQ==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.6'
|
||||
|
||||
react-refresh@0.17.0:
|
||||
resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -1136,6 +1124,9 @@ packages:
|
||||
resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
regenerator-runtime@0.14.1:
|
||||
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
|
||||
|
||||
resolve-from@4.0.0:
|
||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||
engines: {node: '>=4'}
|
||||
@ -1164,6 +1155,9 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
shallow-equal@1.2.1:
|
||||
resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==}
|
||||
|
||||
shebang-command@2.0.0:
|
||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||
engines: {node: '>=8'}
|
||||
@ -1184,12 +1178,18 @@ packages:
|
||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
tailwindcss@4.1.4:
|
||||
resolution: {integrity: sha512-1ZIUqtPITFbv/DxRmDr5/agPqJwF69d24m9qmM1939TJehgY539CtzeZRjbLt5G6fSy/7YqqYsfvoTEw9xUI2A==}
|
||||
symbol-observable@1.2.0:
|
||||
resolution: {integrity: sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
tapable@2.2.1:
|
||||
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
|
||||
engines: {node: '>=6'}
|
||||
theming@3.3.0:
|
||||
resolution: {integrity: sha512-u6l4qTJRDaWZsqa8JugaNt7Xd8PPl9+gonZaIe28vAhqgHMIG/DOyFPqiKN/gQLQYj05tHv+YQdNILL4zoiAVA==}
|
||||
engines: {node: '>=8'}
|
||||
peerDependencies:
|
||||
react: '>=16.3'
|
||||
|
||||
tiny-warning@1.0.3:
|
||||
resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
|
||||
|
||||
tinyglobby@0.2.13:
|
||||
resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==}
|
||||
@ -1286,6 +1286,24 @@ packages:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
zustand@5.0.3:
|
||||
resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==}
|
||||
engines: {node: '>=12.20.0'}
|
||||
peerDependencies:
|
||||
'@types/react': '>=18.0.0'
|
||||
immer: '>=9.0.6'
|
||||
react: '>=18.0.0'
|
||||
use-sync-external-store: '>=1.2.0'
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
immer:
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
use-sync-external-store:
|
||||
optional: true
|
||||
|
||||
snapshots:
|
||||
|
||||
'@ampproject/remapping@2.3.0':
|
||||
@ -1380,6 +1398,10 @@ snapshots:
|
||||
'@babel/core': 7.26.10
|
||||
'@babel/helper-plugin-utils': 7.26.5
|
||||
|
||||
'@babel/runtime@7.27.0':
|
||||
dependencies:
|
||||
regenerator-runtime: 0.14.1
|
||||
|
||||
'@babel/template@7.27.0':
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.26.2
|
||||
@ -1403,6 +1425,12 @@ snapshots:
|
||||
'@babel/helper-string-parser': 7.25.9
|
||||
'@babel/helper-validator-identifier': 7.25.9
|
||||
|
||||
'@emotion/is-prop-valid@0.7.3':
|
||||
dependencies:
|
||||
'@emotion/memoize': 0.7.1
|
||||
|
||||
'@emotion/memoize@0.7.1': {}
|
||||
|
||||
'@esbuild/aix-ppc64@0.25.3':
|
||||
optional: true
|
||||
|
||||
@ -1624,71 +1652,6 @@ snapshots:
|
||||
'@rollup/rollup-win32-x64-msvc@4.40.0':
|
||||
optional: true
|
||||
|
||||
'@tailwindcss/node@4.1.4':
|
||||
dependencies:
|
||||
enhanced-resolve: 5.18.1
|
||||
jiti: 2.4.2
|
||||
lightningcss: 1.29.2
|
||||
tailwindcss: 4.1.4
|
||||
|
||||
'@tailwindcss/oxide-android-arm64@4.1.4':
|
||||
optional: true
|
||||
|
||||
'@tailwindcss/oxide-darwin-arm64@4.1.4':
|
||||
optional: true
|
||||
|
||||
'@tailwindcss/oxide-darwin-x64@4.1.4':
|
||||
optional: true
|
||||
|
||||
'@tailwindcss/oxide-freebsd-x64@4.1.4':
|
||||
optional: true
|
||||
|
||||
'@tailwindcss/oxide-linux-arm-gnueabihf@4.1.4':
|
||||
optional: true
|
||||
|
||||
'@tailwindcss/oxide-linux-arm64-gnu@4.1.4':
|
||||
optional: true
|
||||
|
||||
'@tailwindcss/oxide-linux-arm64-musl@4.1.4':
|
||||
optional: true
|
||||
|
||||
'@tailwindcss/oxide-linux-x64-gnu@4.1.4':
|
||||
optional: true
|
||||
|
||||
'@tailwindcss/oxide-linux-x64-musl@4.1.4':
|
||||
optional: true
|
||||
|
||||
'@tailwindcss/oxide-wasm32-wasi@4.1.4':
|
||||
optional: true
|
||||
|
||||
'@tailwindcss/oxide-win32-arm64-msvc@4.1.4':
|
||||
optional: true
|
||||
|
||||
'@tailwindcss/oxide-win32-x64-msvc@4.1.4':
|
||||
optional: true
|
||||
|
||||
'@tailwindcss/oxide@4.1.4':
|
||||
optionalDependencies:
|
||||
'@tailwindcss/oxide-android-arm64': 4.1.4
|
||||
'@tailwindcss/oxide-darwin-arm64': 4.1.4
|
||||
'@tailwindcss/oxide-darwin-x64': 4.1.4
|
||||
'@tailwindcss/oxide-freebsd-x64': 4.1.4
|
||||
'@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.4
|
||||
'@tailwindcss/oxide-linux-arm64-gnu': 4.1.4
|
||||
'@tailwindcss/oxide-linux-arm64-musl': 4.1.4
|
||||
'@tailwindcss/oxide-linux-x64-gnu': 4.1.4
|
||||
'@tailwindcss/oxide-linux-x64-musl': 4.1.4
|
||||
'@tailwindcss/oxide-wasm32-wasi': 4.1.4
|
||||
'@tailwindcss/oxide-win32-arm64-msvc': 4.1.4
|
||||
'@tailwindcss/oxide-win32-x64-msvc': 4.1.4
|
||||
|
||||
'@tailwindcss/vite@4.1.4(vite@6.3.3(jiti@2.4.2)(lightningcss@1.29.2))':
|
||||
dependencies:
|
||||
'@tailwindcss/node': 4.1.4
|
||||
'@tailwindcss/oxide': 4.1.4
|
||||
tailwindcss: 4.1.4
|
||||
vite: 6.3.3(jiti@2.4.2)(lightningcss@1.29.2)
|
||||
|
||||
'@types/babel__core@7.20.5':
|
||||
dependencies:
|
||||
'@babel/parser': 7.27.0
|
||||
@ -1876,6 +1839,17 @@ snapshots:
|
||||
shebang-command: 2.0.0
|
||||
which: 2.0.2
|
||||
|
||||
css-jss@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
jss: 10.10.0
|
||||
jss-preset-default: 10.10.0
|
||||
|
||||
css-vendor@2.0.8:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
is-in-browser: 1.1.3
|
||||
|
||||
csstype@3.1.3: {}
|
||||
|
||||
debug@4.4.0:
|
||||
@ -1884,15 +1858,11 @@ snapshots:
|
||||
|
||||
deep-is@0.1.4: {}
|
||||
|
||||
detect-libc@2.0.4: {}
|
||||
detect-libc@2.0.4:
|
||||
optional: true
|
||||
|
||||
electron-to-chromium@1.5.143: {}
|
||||
|
||||
enhanced-resolve@5.18.1:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
tapable: 2.2.1
|
||||
|
||||
esbuild@0.25.3:
|
||||
optionalDependencies:
|
||||
'@esbuild/aix-ppc64': 0.25.3
|
||||
@ -2063,12 +2033,16 @@ snapshots:
|
||||
|
||||
globals@16.0.0: {}
|
||||
|
||||
graceful-fs@4.2.11: {}
|
||||
|
||||
graphemer@1.4.0: {}
|
||||
|
||||
has-flag@4.0.0: {}
|
||||
|
||||
hoist-non-react-statics@3.3.2:
|
||||
dependencies:
|
||||
react-is: 16.13.1
|
||||
|
||||
hyphenate-style-name@1.1.0: {}
|
||||
|
||||
ignore@5.3.2: {}
|
||||
|
||||
import-fresh@3.3.1:
|
||||
@ -2084,11 +2058,14 @@ snapshots:
|
||||
dependencies:
|
||||
is-extglob: 2.1.1
|
||||
|
||||
is-in-browser@1.1.3: {}
|
||||
|
||||
is-number@7.0.0: {}
|
||||
|
||||
isexe@2.0.0: {}
|
||||
|
||||
jiti@2.4.2: {}
|
||||
jiti@2.4.2:
|
||||
optional: true
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
|
||||
@ -2106,6 +2083,98 @@ snapshots:
|
||||
|
||||
json5@2.2.3: {}
|
||||
|
||||
jss-plugin-camel-case@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
hyphenate-style-name: 1.1.0
|
||||
jss: 10.10.0
|
||||
|
||||
jss-plugin-compose@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
jss: 10.10.0
|
||||
tiny-warning: 1.0.3
|
||||
|
||||
jss-plugin-default-unit@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
jss: 10.10.0
|
||||
|
||||
jss-plugin-expand@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
jss: 10.10.0
|
||||
|
||||
jss-plugin-extend@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
jss: 10.10.0
|
||||
tiny-warning: 1.0.3
|
||||
|
||||
jss-plugin-global@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
jss: 10.10.0
|
||||
|
||||
jss-plugin-nested@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
jss: 10.10.0
|
||||
tiny-warning: 1.0.3
|
||||
|
||||
jss-plugin-props-sort@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
jss: 10.10.0
|
||||
|
||||
jss-plugin-rule-value-function@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
jss: 10.10.0
|
||||
tiny-warning: 1.0.3
|
||||
|
||||
jss-plugin-rule-value-observable@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
jss: 10.10.0
|
||||
symbol-observable: 1.2.0
|
||||
|
||||
jss-plugin-template@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
jss: 10.10.0
|
||||
tiny-warning: 1.0.3
|
||||
|
||||
jss-plugin-vendor-prefixer@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
css-vendor: 2.0.8
|
||||
jss: 10.10.0
|
||||
|
||||
jss-preset-default@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
jss: 10.10.0
|
||||
jss-plugin-camel-case: 10.10.0
|
||||
jss-plugin-compose: 10.10.0
|
||||
jss-plugin-default-unit: 10.10.0
|
||||
jss-plugin-expand: 10.10.0
|
||||
jss-plugin-extend: 10.10.0
|
||||
jss-plugin-global: 10.10.0
|
||||
jss-plugin-nested: 10.10.0
|
||||
jss-plugin-props-sort: 10.10.0
|
||||
jss-plugin-rule-value-function: 10.10.0
|
||||
jss-plugin-rule-value-observable: 10.10.0
|
||||
jss-plugin-template: 10.10.0
|
||||
jss-plugin-vendor-prefixer: 10.10.0
|
||||
|
||||
jss@10.10.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
csstype: 3.1.3
|
||||
is-in-browser: 1.1.3
|
||||
tiny-warning: 1.0.3
|
||||
|
||||
keyv@4.5.4:
|
||||
dependencies:
|
||||
json-buffer: 3.0.1
|
||||
@ -2159,6 +2228,7 @@ snapshots:
|
||||
lightningcss-linux-x64-musl: 1.29.2
|
||||
lightningcss-win32-arm64-msvc: 1.29.2
|
||||
lightningcss-win32-x64-msvc: 1.29.2
|
||||
optional: true
|
||||
|
||||
locate-path@6.0.0:
|
||||
dependencies:
|
||||
@ -2166,6 +2236,10 @@ snapshots:
|
||||
|
||||
lodash.merge@4.6.2: {}
|
||||
|
||||
loose-envify@1.4.0:
|
||||
dependencies:
|
||||
js-tokens: 4.0.0
|
||||
|
||||
lru-cache@5.1.1:
|
||||
dependencies:
|
||||
yallist: 3.1.1
|
||||
@ -2193,6 +2267,8 @@ snapshots:
|
||||
|
||||
node-releases@2.0.19: {}
|
||||
|
||||
object-assign@4.1.1: {}
|
||||
|
||||
optionator@0.9.4:
|
||||
dependencies:
|
||||
deep-is: 0.1.4
|
||||
@ -2232,19 +2308,46 @@ snapshots:
|
||||
|
||||
prelude-ls@1.2.1: {}
|
||||
|
||||
prop-types@15.8.1:
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
object-assign: 4.1.1
|
||||
react-is: 16.13.1
|
||||
|
||||
punycode@2.3.1: {}
|
||||
|
||||
queue-microtask@1.2.3: {}
|
||||
|
||||
react-display-name@0.2.5: {}
|
||||
|
||||
react-dom@19.1.0(react@19.1.0):
|
||||
dependencies:
|
||||
react: 19.1.0
|
||||
scheduler: 0.26.0
|
||||
|
||||
react-is@16.13.1: {}
|
||||
|
||||
react-jss@10.10.0(react@19.1.0):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.0
|
||||
'@emotion/is-prop-valid': 0.7.3
|
||||
css-jss: 10.10.0
|
||||
hoist-non-react-statics: 3.3.2
|
||||
is-in-browser: 1.1.3
|
||||
jss: 10.10.0
|
||||
jss-preset-default: 10.10.0
|
||||
prop-types: 15.8.1
|
||||
react: 19.1.0
|
||||
shallow-equal: 1.2.1
|
||||
theming: 3.3.0(react@19.1.0)
|
||||
tiny-warning: 1.0.3
|
||||
|
||||
react-refresh@0.17.0: {}
|
||||
|
||||
react@19.1.0: {}
|
||||
|
||||
regenerator-runtime@0.14.1: {}
|
||||
|
||||
resolve-from@4.0.0: {}
|
||||
|
||||
reusify@1.1.0: {}
|
||||
@ -2285,6 +2388,8 @@ snapshots:
|
||||
|
||||
semver@7.7.1: {}
|
||||
|
||||
shallow-equal@1.2.1: {}
|
||||
|
||||
shebang-command@2.0.0:
|
||||
dependencies:
|
||||
shebang-regex: 3.0.0
|
||||
@ -2299,9 +2404,17 @@ snapshots:
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
|
||||
tailwindcss@4.1.4: {}
|
||||
symbol-observable@1.2.0: {}
|
||||
|
||||
tapable@2.2.1: {}
|
||||
theming@3.3.0(react@19.1.0):
|
||||
dependencies:
|
||||
hoist-non-react-statics: 3.3.2
|
||||
prop-types: 15.8.1
|
||||
react: 19.1.0
|
||||
react-display-name: 0.2.5
|
||||
tiny-warning: 1.0.3
|
||||
|
||||
tiny-warning@1.0.3: {}
|
||||
|
||||
tinyglobby@0.2.13:
|
||||
dependencies:
|
||||
@ -2364,3 +2477,8 @@ snapshots:
|
||||
yallist@3.1.1: {}
|
||||
|
||||
yocto-queue@0.1.0: {}
|
||||
|
||||
zustand@5.0.3(@types/react@19.1.2)(react@19.1.0):
|
||||
optionalDependencies:
|
||||
'@types/react': 19.1.2
|
||||
react: 19.1.0
|
||||
|
33
frontend/src/component/button/u-button.tsx
Normal file
33
frontend/src/component/button/u-button.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import React, {ReactNode} from 'react';
|
||||
import {createUseStyles} from "react-jss";
|
||||
|
||||
const useStyle = createUseStyles({
|
||||
ubutton: {
|
||||
backgroundColor: "#4CAF50",
|
||||
color: "white",
|
||||
padding: "10px 20px",
|
||||
border: "none",
|
||||
borderRadius: "5px",
|
||||
cursor: "pointer",
|
||||
transition: "background-color 0.3s",
|
||||
"&:hover": {
|
||||
backgroundColor: "#45a049",
|
||||
},
|
||||
"&:disabled": {
|
||||
backgroundColor: "#a5d6a7",
|
||||
cursor: "not-allowed",
|
||||
},
|
||||
}
|
||||
})
|
||||
type Props = {
|
||||
onClick: () => void;
|
||||
children: ReactNode;
|
||||
disabled?: boolean;
|
||||
style?: React.CSSProperties | undefined;
|
||||
};
|
||||
export const UButton: React.FC<Props> = ({onClick, children, style,disabled = false}) => {
|
||||
const classes= useStyle()
|
||||
return <button style={style} className={classes.ubutton} disabled={disabled} onClick={onClick}>
|
||||
{children}
|
||||
</button>
|
||||
}
|
85
frontend/src/page/component/panel-left.tsx
Normal file
85
frontend/src/page/component/panel-left.tsx
Normal file
@ -0,0 +1,85 @@
|
||||
import {createUseStyles} from "react-jss";
|
||||
import {UButton} from "../../component/button/u-button.tsx";
|
||||
import React from "react";
|
||||
import {useStore} from "../../store/share.ts";
|
||||
|
||||
const useStyle = createUseStyles({
|
||||
container: {
|
||||
backgroundColor: "#e3f2fd",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
form: {
|
||||
backgroundColor: "#C8E6C9",
|
||||
boxShadow: "inset 0 0 15px rgba(56, 142, 60, 0.15)",
|
||||
padding: "30px",
|
||||
borderRadius: "15px",
|
||||
width: "70%",
|
||||
margin: "20px 60px 20px 0",
|
||||
/*todo margin 不用 px*/
|
||||
},
|
||||
title: {
|
||||
color: "#2c9678"
|
||||
},
|
||||
file: {
|
||||
display: 'none',
|
||||
},
|
||||
preview: {
|
||||
marginTop: '10px',
|
||||
display: 'flex',
|
||||
},
|
||||
name: {
|
||||
color: "#2c9678",
|
||||
marginLeft: '10px'
|
||||
},
|
||||
clean: {
|
||||
borderRadius: '50%',
|
||||
cursor: 'pointer',
|
||||
'&:hover': {}
|
||||
}
|
||||
})
|
||||
export const PanelLeft = () => {
|
||||
const style = useStyle()
|
||||
const {file, setFile} = useStore()
|
||||
|
||||
function onFileSelect() {
|
||||
// @ts-ignore
|
||||
document.querySelector('#real-file-input').click();
|
||||
}
|
||||
|
||||
function onFileChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
console.log('[D] onFileChange: e =', e)
|
||||
setFile(e.currentTarget.files ? e.currentTarget.files[0] : null)
|
||||
}
|
||||
|
||||
function onFileUpload() {
|
||||
console.log('[D] onFileUpload: upload file =', file)
|
||||
}
|
||||
|
||||
function onFileClean() {
|
||||
setFile(null)
|
||||
}
|
||||
|
||||
return <div className={style.container}>
|
||||
<div className={style.form}>
|
||||
<h2 className={style.title}>上传文件</h2>
|
||||
{
|
||||
!file &&
|
||||
<UButton onClick={onFileSelect}>选择文件</UButton>
|
||||
}
|
||||
{
|
||||
file &&
|
||||
<UButton onClick={onFileUpload}>上传文件</UButton>
|
||||
}
|
||||
<input type="file" className={style.file} id="real-file-input" onChange={onFileChange}/>
|
||||
{
|
||||
file &&
|
||||
<div className={style.preview}>
|
||||
<div className={style.clean} onClick={onFileClean}>×</div>
|
||||
<div className={style.name}>{file.name}</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
};
|
29
frontend/src/page/component/panel-mid.tsx
Normal file
29
frontend/src/page/component/panel-mid.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import {createUseStyles} from "react-jss";
|
||||
|
||||
const useStyle = createUseStyles({
|
||||
container: {
|
||||
position: "relative",
|
||||
overflow: "hidden",
|
||||
},
|
||||
left: {
|
||||
backgroundColor: "#e3f2fd",
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
clipPath: 'polygon(0 0, 100% 0, 0 100%)'
|
||||
},
|
||||
right: {
|
||||
backgroundColor: "#e8f5e9",
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
clipPath: 'polygon(100% 0, 100% 100%, 0 100%)'
|
||||
},
|
||||
})
|
||||
export const PanelMid = () => {
|
||||
const style = useStyle()
|
||||
return <div className={style.container}>
|
||||
<div className={style.left}></div>
|
||||
<div className={style.right}></div>
|
||||
</div>
|
||||
};
|
68
frontend/src/page/component/panel-right.tsx
Normal file
68
frontend/src/page/component/panel-right.tsx
Normal file
@ -0,0 +1,68 @@
|
||||
import {createUseStyles} from "react-jss";
|
||||
import {UButton} from "../../component/button/u-button.tsx";
|
||||
import {useStore} from "../../store/share.ts";
|
||||
|
||||
const useStyle = createUseStyles({
|
||||
container: {
|
||||
backgroundColor: "#e8f5e9",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
form: {
|
||||
backgroundColor: "#BBDEFB",
|
||||
boxShadow: "inset 0 0 15px rgba(33, 150, 243, 0.15)",
|
||||
padding: "30px",
|
||||
borderRadius: "15px",
|
||||
width: "70%",
|
||||
margin: "20px 0 20px 60px",
|
||||
/*todo margin 不用 px*/
|
||||
},
|
||||
title: {
|
||||
color: '#1661ab', // 靛青
|
||||
},
|
||||
code: {
|
||||
padding: '11px',
|
||||
margin: '20px 0',
|
||||
width: '200px',
|
||||
border: '2px solid #ddd',
|
||||
borderRadius: '5px',
|
||||
'&:active': {
|
||||
border: '2px solid #1661ab',
|
||||
}
|
||||
}
|
||||
})
|
||||
export const PanelRight = () => {
|
||||
const style = useStyle()
|
||||
const {code, setCode} = useStore()
|
||||
|
||||
function onCodeChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
setCode(e.currentTarget.value)
|
||||
}
|
||||
|
||||
async function onFetchFile() {
|
||||
const url = `/api/share/fetch?code=${code}`
|
||||
console.log('[D] onFetchFile: url =', url)
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
|
||||
return <div className={style.container}>
|
||||
<div className={style.form}>
|
||||
<h2 className={style.title}>获取文件</h2>
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
className={style.code}
|
||||
placeholder="输入下载码"
|
||||
value={code}
|
||||
onChange={onCodeChange}
|
||||
/>
|
||||
<UButton style={{marginLeft: '10px'}} onClick={onFetchFile}>获取文件</UButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
};
|
@ -1,15 +0,0 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
.mid-left {
|
||||
background-color: #e3f2fd; /* 柔和的浅蓝色 */
|
||||
}
|
||||
.mid-right {
|
||||
background-color: #e8f5e9; /* 柔和的浅绿色 */
|
||||
}
|
||||
|
||||
.share-left {
|
||||
background-color: #e3f2fd; /* 柔和的浅蓝色 */
|
||||
}
|
||||
.share-right {
|
||||
background-color: #e8f5e9;
|
||||
}
|
@ -1,130 +1,26 @@
|
||||
import "./share.css";
|
||||
// FileSharing.tsx
|
||||
import { useRef, useState } from 'react';
|
||||
import {createUseStyles} from 'react-jss'
|
||||
import {PanelLeft} from "./component/panel-left.tsx";
|
||||
import {PanelRight} from "./component/panel-right.tsx";
|
||||
import {PanelMid} from "./component/panel-mid.tsx";
|
||||
|
||||
type FileItemProps = {
|
||||
fileName: string;
|
||||
onClear: () => void;
|
||||
};
|
||||
const useStyle = createUseStyles({
|
||||
"@global": {
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
},
|
||||
container: {
|
||||
margin: 0,
|
||||
height: "100vh",
|
||||
display: "grid",
|
||||
gridTemplateColumns: "40% 20% 40%",
|
||||
},
|
||||
})
|
||||
|
||||
const FileItem = ({ fileName, onClear }: FileItemProps) => (
|
||||
<div className="flex items-center gap-2 my-2">
|
||||
<button
|
||||
className="w-5 h-5 rounded-full flex items-center justify-center text-white hover:bg-red-400 transition-colors"
|
||||
onClick={onClear}
|
||||
>
|
||||
×
|
||||
</button>
|
||||
<span className="text-gray-700">{fileName}</span>
|
||||
export const FileSharing = () => {
|
||||
const style = useStyle()
|
||||
return <div className={style.container}>
|
||||
<PanelLeft />
|
||||
<PanelMid/>
|
||||
<PanelRight/>
|
||||
</div>
|
||||
);
|
||||
|
||||
const MiddlePanel = () => (
|
||||
<div className="relative bg-gray-200 overflow-hidden">
|
||||
<div
|
||||
className="mid-left absolute w-full h-full bg-blue-100"
|
||||
style={{ clipPath: 'polygon(0 0, 100% 0, 0 100%)' }}
|
||||
/>
|
||||
<div
|
||||
className="mid-right absolute w-full h-full bg-green-100"
|
||||
style={{ clipPath: 'polygon(100% 0, 100% 100%, 0 100%)' }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
const UploadPanel = () => {
|
||||
const [selectedFile, setSelectedFile] = useState<File | null>(null);
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const handleFileSelect = () => {
|
||||
if (!selectedFile && fileInputRef.current) {
|
||||
fileInputRef.current.click();
|
||||
} else {
|
||||
// Handle upload logic
|
||||
if (selectedFile) {
|
||||
const formData = new FormData();
|
||||
formData.append('file', selectedFile);
|
||||
|
||||
// Replace with actual API call
|
||||
fetch('https://your-upload-api.com/upload', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
alert(`Upload success! Code: ${data.code}`);
|
||||
setSelectedFile(null);
|
||||
})
|
||||
.catch(() => alert('Upload failed'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="share-left flex flex-col items-center justify-center p-5 bg-blue-50 h-full">
|
||||
<div className="bg-blue-100 rounded-xl p-6 w-4/5 shadow-inner">
|
||||
<h2 className="text-xl font-semibold mb-4 text-cyan-900">上传文件</h2>
|
||||
<input
|
||||
type="file"
|
||||
ref={fileInputRef}
|
||||
className="hidden"
|
||||
onChange={(e) => e.target.files?.[0] && setSelectedFile(e.target.files[0])}
|
||||
/>
|
||||
<button
|
||||
onClick={handleFileSelect}
|
||||
className="bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 transition-colors"
|
||||
>
|
||||
{selectedFile ? '确认上传' : '选择文件'}
|
||||
</button>
|
||||
{selectedFile && (
|
||||
<FileItem
|
||||
fileName={selectedFile.name}
|
||||
onClear={() => setSelectedFile(null)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const DownloadPanel = () => {
|
||||
const [downloadCode, setDownloadCode] = useState('');
|
||||
|
||||
const handleDownload = () => {
|
||||
if (!downloadCode) {
|
||||
alert('请输入下载码');
|
||||
return;
|
||||
}
|
||||
// Replace with actual download logic
|
||||
window.location.href = `https://your-download-api.com/download?code=${downloadCode}`;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="share-right flex flex-col items-center justify-center p-5 bg-green-50 h-full">
|
||||
<div className="bg-green-100 rounded-xl p-6 w-4/5 shadow-inner">
|
||||
<h2 className="text-xl font-semibold mb-4 text-teal-900">下载文件</h2>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="输入下载码"
|
||||
className="w-full px-3 py-2 border-2 border-gray-200 rounded-lg mb-4"
|
||||
value={downloadCode}
|
||||
onChange={(e) => setDownloadCode(e.target.value)}
|
||||
/>
|
||||
<button
|
||||
onClick={handleDownload}
|
||||
className="bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 transition-colors w-full"
|
||||
>
|
||||
下载文件
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const FileSharing = () => (
|
||||
<div className="h-screen grid grid-cols-[40%_20%_40%]">
|
||||
<UploadPanel />
|
||||
<MiddlePanel />
|
||||
<DownloadPanel />
|
||||
</div>
|
||||
);
|
||||
};
|
23
frontend/src/store/share.ts
Normal file
23
frontend/src/store/share.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import {create} from 'zustand'
|
||||
|
||||
type Store = {
|
||||
file: File | null,
|
||||
setFile: (f: File | null) => void
|
||||
code: string,
|
||||
setCode: (value:string) => void
|
||||
}
|
||||
|
||||
export const useStore = create<Store>()((set) => ({
|
||||
file: null,
|
||||
setFile: (f: File | null = null) => {
|
||||
set(state => {
|
||||
return {...state, file: f}
|
||||
})
|
||||
},
|
||||
code: '',
|
||||
setCode: (value:string= '') => {
|
||||
set(state => {
|
||||
return {...state, code: value}
|
||||
})
|
||||
}
|
||||
}))
|
@ -1,8 +1,15 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import tailwindcss from '@tailwindcss/vite'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react(), tailwindcss()],
|
||||
plugins: [react()],
|
||||
server: {
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://127.0.0.1:9119',
|
||||
changeOrigin: true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
Reference in New Issue
Block a user