feat(createRecord): interface

This commit is contained in:
Serafim 2025-01-29 14:57:12 +03:00
parent 500c51305a
commit f588f69f66
19 changed files with 1103 additions and 19 deletions

View File

@ -22,6 +22,7 @@ Authorization: Bearer
Record {
id: int
owner: string
description: string
weight: number
calories: number
@ -29,7 +30,7 @@ Record {
date: datetime
}
GET /records?offset=0&amount=5
GET /records?offset=0&amount=5&query=""
[
{
date: string

View File

@ -6,7 +6,7 @@ services:
- ./nginx:/etc/nginx/conf.d
- ./frontend/dist:/usr/share/nginx/html
ports:
- 80:80
- ${PORT}:80
depends_on:
- backend
- keycloak

View File

@ -9,6 +9,9 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@base-ui-components/react": "^1.0.0-alpha.5",
"@bem-react/classname": "^1.6.0",
"@bem-react/classnames": "^1.3.10",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@mui/material": "^6.4.1",
@ -189,6 +192,49 @@
"node": ">=6.9.0"
}
},
"node_modules/@base-ui-components/react": {
"version": "1.0.0-alpha.5",
"resolved": "https://registry.npmjs.org/@base-ui-components/react/-/react-1.0.0-alpha.5.tgz",
"integrity": "sha512-/hkuXkfiuMZpX1rp1alx2QAah7dUnojgUxtmbEjxYaeS7xiifw9N645ek8e3Dd3QPhVYmDZYfqj/aYUS0IwIqA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.26.0",
"@floating-ui/react": "^0.27.3",
"@floating-ui/utils": "^0.2.9",
"@react-aria/overlays": "^3.24.0",
"prop-types": "^15.8.1",
"use-sync-external-store": "^1.4.0"
},
"engines": {
"node": ">=14.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mui-org"
},
"peerDependencies": {
"@types/react": "^17 || ^18 || ^19",
"react": "^17 || ^18 || ^19",
"react-dom": "^17 || ^18 || ^19"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@bem-react/classname": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@bem-react/classname/-/classname-1.6.0.tgz",
"integrity": "sha512-SFBwUHMcb7TFFK5ld88+JhecoEun3/kHZ6KvLDjj3w5hv/tfRV8mtGHA8N42uMctXLF4bPEcr96xwXXcRFuweg==",
"license": "MPL-2.0"
},
"node_modules/@bem-react/classnames": {
"version": "1.3.10",
"resolved": "https://registry.npmjs.org/@bem-react/classnames/-/classnames-1.3.10.tgz",
"integrity": "sha512-tn+45Ii+S5FcYuO5FMs9YLSMUc355iUho7mwFeMMihi/ZZCQjvdR5AhVexnL9GS7pMtOeV0OsDOPDkW1sXVI3A==",
"license": "MPL-2.0"
},
"node_modules/@discoveryjs/json-ext": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz",
@ -354,6 +400,147 @@
"integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==",
"license": "MIT"
},
"node_modules/@floating-ui/core": {
"version": "1.6.9",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz",
"integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==",
"license": "MIT",
"dependencies": {
"@floating-ui/utils": "^0.2.9"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.6.13",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz",
"integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==",
"license": "MIT",
"dependencies": {
"@floating-ui/core": "^1.6.0",
"@floating-ui/utils": "^0.2.9"
}
},
"node_modules/@floating-ui/react": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.3.tgz",
"integrity": "sha512-CLHnes3ixIFFKVQDdICjel8muhFLOBdQH7fgtHNPY8UbCNqbeKZ262G7K66lGQOUQWWnYocf7ZbUsLJgGfsLHg==",
"license": "MIT",
"dependencies": {
"@floating-ui/react-dom": "^2.1.2",
"@floating-ui/utils": "^0.2.9",
"tabbable": "^6.0.0"
},
"peerDependencies": {
"react": ">=17.0.0",
"react-dom": ">=17.0.0"
}
},
"node_modules/@floating-ui/react-dom": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz",
"integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==",
"license": "MIT",
"dependencies": {
"@floating-ui/dom": "^1.0.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.9",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
"integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
"license": "MIT"
},
"node_modules/@formatjs/ecma402-abstract": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.2.tgz",
"integrity": "sha512-6sE5nyvDloULiyOMbOTJEEgWL32w+VHkZQs8S02Lnn8Y/O5aQhjOEXwWzvR7SsBE/exxlSpY2EsWZgqHbtLatg==",
"license": "MIT",
"dependencies": {
"@formatjs/fast-memoize": "2.2.6",
"@formatjs/intl-localematcher": "0.5.10",
"decimal.js": "10",
"tslib": "2"
}
},
"node_modules/@formatjs/fast-memoize": {
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.6.tgz",
"integrity": "sha512-luIXeE2LJbQnnzotY1f2U2m7xuQNj2DA8Vq4ce1BY9ebRZaoPB1+8eZ6nXpLzsxuW5spQxr7LdCg+CApZwkqkw==",
"license": "MIT",
"dependencies": {
"tslib": "2"
}
},
"node_modules/@formatjs/icu-messageformat-parser": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.0.tgz",
"integrity": "sha512-Hp81uTjjdTk3FLh/dggU5NK7EIsVWc5/ZDWrIldmf2rBuPejuZ13CZ/wpVE2SToyi4EiroPTQ1XJcJuZFIxTtw==",
"license": "MIT",
"dependencies": {
"@formatjs/ecma402-abstract": "2.3.2",
"@formatjs/icu-skeleton-parser": "1.8.12",
"tslib": "2"
}
},
"node_modules/@formatjs/icu-skeleton-parser": {
"version": "1.8.12",
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.12.tgz",
"integrity": "sha512-QRAY2jC1BomFQHYDMcZtClqHR55EEnB96V7Xbk/UiBodsuFc5kujybzt87+qj1KqmJozFhk6n4KiT1HKwAkcfg==",
"license": "MIT",
"dependencies": {
"@formatjs/ecma402-abstract": "2.3.2",
"tslib": "2"
}
},
"node_modules/@formatjs/intl-localematcher": {
"version": "0.5.10",
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.10.tgz",
"integrity": "sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==",
"license": "MIT",
"dependencies": {
"tslib": "2"
}
},
"node_modules/@internationalized/date": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.7.0.tgz",
"integrity": "sha512-VJ5WS3fcVx0bejE/YHfbDKR/yawZgKqn/if+oEeLqNwBtPzVB06olkfcnojTmEMX+gTpH+FlQ69SHNitJ8/erQ==",
"license": "Apache-2.0",
"dependencies": {
"@swc/helpers": "^0.5.0"
}
},
"node_modules/@internationalized/message": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/@internationalized/message/-/message-3.1.6.tgz",
"integrity": "sha512-JxbK3iAcTIeNr1p0WIFg/wQJjIzJt9l/2KNY/48vXV7GRGZSv3zMxJsce008fZclk2cDC8y0Ig3odceHO7EfNQ==",
"license": "Apache-2.0",
"dependencies": {
"@swc/helpers": "^0.5.0",
"intl-messageformat": "^10.1.0"
}
},
"node_modules/@internationalized/number": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.0.tgz",
"integrity": "sha512-PtrRcJVy7nw++wn4W2OuePQQfTqDzfusSuY1QTtui4wa7r+rGVtR75pO8CyKvHvzyQYi3Q1uO5sY0AsB4e65Bw==",
"license": "Apache-2.0",
"dependencies": {
"@swc/helpers": "^0.5.0"
}
},
"node_modules/@internationalized/string": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/@internationalized/string/-/string-3.2.5.tgz",
"integrity": "sha512-rKs71Zvl2OKOHM+mzAFMIyqR5hI1d1O6BBkMK2/lkfg3fkmVh9Eeg0awcA8W2WqYqDOv6a86DIOlFpggwLtbuw==",
"license": "Apache-2.0",
"dependencies": {
"@swc/helpers": "^0.5.0"
}
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
@ -1001,6 +1188,198 @@
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@react-aria/focus": {
"version": "3.19.1",
"resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.19.1.tgz",
"integrity": "sha512-bix9Bu1Ue7RPcYmjwcjhB14BMu2qzfJ3tMQLqDc9pweJA66nOw8DThy3IfVr8Z7j2PHktOLf9kcbiZpydKHqzg==",
"license": "Apache-2.0",
"dependencies": {
"@react-aria/interactions": "^3.23.0",
"@react-aria/utils": "^3.27.0",
"@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0",
"clsx": "^2.0.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
"react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/i18n": {
"version": "3.12.5",
"resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.12.5.tgz",
"integrity": "sha512-ooeop2pTG94PuaHoN2OTk2hpkqVuoqgEYxRvnc1t7DVAtsskfhS/gVOTqyWGsxvwAvRi7m/CnDu6FYdeQ/bK5w==",
"license": "Apache-2.0",
"dependencies": {
"@internationalized/date": "^3.7.0",
"@internationalized/message": "^3.1.6",
"@internationalized/number": "^3.6.0",
"@internationalized/string": "^3.2.5",
"@react-aria/ssr": "^3.9.7",
"@react-aria/utils": "^3.27.0",
"@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
"react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/interactions": {
"version": "3.23.0",
"resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.23.0.tgz",
"integrity": "sha512-0qR1atBIWrb7FzQ+Tmr3s8uH5mQdyRH78n0krYaG8tng9+u1JlSi8DGRSaC9ezKyNB84m7vHT207xnHXGeJ3Fg==",
"license": "Apache-2.0",
"dependencies": {
"@react-aria/ssr": "^3.9.7",
"@react-aria/utils": "^3.27.0",
"@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
"react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/overlays": {
"version": "3.25.0",
"resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.25.0.tgz",
"integrity": "sha512-UEqJJ4duowrD1JvwXpPZreBuK79pbyNjNxFUVpFSskpGEJe3oCWwsSDKz7P1O7xbx5OYp+rDiY8fk/sE5rkaKw==",
"license": "Apache-2.0",
"dependencies": {
"@react-aria/focus": "^3.19.1",
"@react-aria/i18n": "^3.12.5",
"@react-aria/interactions": "^3.23.0",
"@react-aria/ssr": "^3.9.7",
"@react-aria/utils": "^3.27.0",
"@react-aria/visually-hidden": "^3.8.19",
"@react-stately/overlays": "^3.6.13",
"@react-types/button": "^3.10.2",
"@react-types/overlays": "^3.8.12",
"@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
"react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/ssr": {
"version": "3.9.7",
"resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.7.tgz",
"integrity": "sha512-GQygZaGlmYjmYM+tiNBA5C6acmiDWF52Nqd40bBp0Znk4M4hP+LTmI0lpI1BuKMw45T8RIhrAsICIfKwZvi2Gg==",
"license": "Apache-2.0",
"dependencies": {
"@swc/helpers": "^0.5.0"
},
"engines": {
"node": ">= 12"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/utils": {
"version": "3.27.0",
"resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.27.0.tgz",
"integrity": "sha512-p681OtApnKOdbeN8ITfnnYqfdHS0z7GE+4l8EXlfLnr70Rp/9xicBO6d2rU+V/B3JujDw2gPWxYKEnEeh0CGCw==",
"license": "Apache-2.0",
"dependencies": {
"@react-aria/ssr": "^3.9.7",
"@react-stately/utils": "^3.10.5",
"@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0",
"clsx": "^2.0.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
"react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/visually-hidden": {
"version": "3.8.19",
"resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.19.tgz",
"integrity": "sha512-MZgCCyQ3sdG94J5iJz7I7Ai3IxoN0U5d/+EaUnA1mfK7jf2fSYQBqi6Eyp8sWUYzBTLw4giXB5h0RGAnWzk9hA==",
"license": "Apache-2.0",
"dependencies": {
"@react-aria/interactions": "^3.23.0",
"@react-aria/utils": "^3.27.0",
"@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
"react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/overlays": {
"version": "3.6.13",
"resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.13.tgz",
"integrity": "sha512-WsU85Gf/b+HbWsnnYw7P/Ila3wD+C37Uk/WbU4/fHgJ26IEOWsPE6wlul8j54NZ1PnLNhV9Fn+Kffi+PaJMQXQ==",
"license": "Apache-2.0",
"dependencies": {
"@react-stately/utils": "^3.10.5",
"@react-types/overlays": "^3.8.12",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/utils": {
"version": "3.10.5",
"resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.5.tgz",
"integrity": "sha512-iMQSGcpaecghDIh3mZEpZfoFH3ExBwTtuBEcvZ2XnGzCgQjeYXcMdIUwAfVQLXFTdHUHGF6Gu6/dFrYsCzySBQ==",
"license": "Apache-2.0",
"dependencies": {
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/button": {
"version": "3.10.2",
"resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.10.2.tgz",
"integrity": "sha512-h8SB/BLoCgoBulCpyzaoZ+miKXrolK9XC48+n1dKJXT8g4gImrficurDW6+PRTQWaRai0Q0A6bu8UibZOU4syg==",
"license": "Apache-2.0",
"dependencies": {
"@react-types/shared": "^3.27.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/overlays": {
"version": "3.8.12",
"resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.8.12.tgz",
"integrity": "sha512-ZvR1t0YV7/6j+6OD8VozKYjvsXT92+C/2LOIKozy7YUNS5KI4MkXbRZzJvkuRECVZOmx8JXKTUzhghWJM/3QuQ==",
"license": "Apache-2.0",
"dependencies": {
"@react-types/shared": "^3.27.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/shared": {
"version": "3.27.0",
"resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.27.0.tgz",
"integrity": "sha512-gvznmLhi6JPEf0bsq7SwRYTHAKKq/wcmKqFez9sRdbED+SPMUmK5omfZ6w3EwUFQHbYUa4zPBYedQ7Knv70RMw==",
"license": "Apache-2.0",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@swc/helpers": {
"version": "0.5.15",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
"integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.8.0"
}
},
"node_modules/@types/body-parser": {
"version": "1.19.5",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
@ -2260,6 +2639,12 @@
"ms": "2.0.0"
}
},
"node_modules/decimal.js": {
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz",
"integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==",
"license": "MIT"
},
"node_modules/default-browser": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
@ -3379,6 +3764,18 @@
"node": ">=10.13.0"
}
},
"node_modules/intl-messageformat": {
"version": "10.7.14",
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.14.tgz",
"integrity": "sha512-mMGnE4E1otdEutV5vLUdCxRJygHB5ozUBxsPB5qhitewssrS/qGruq9bmvIRkkGsNeK5ZWLfYRld18UHGTIifQ==",
"license": "BSD-3-Clause",
"dependencies": {
"@formatjs/ecma402-abstract": "2.3.2",
"@formatjs/fast-memoize": "2.2.6",
"@formatjs/icu-messageformat-parser": "2.11.0",
"tslib": "2"
}
},
"node_modules/ipaddr.js": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz",
@ -5371,6 +5768,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/tabbable": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
"integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==",
"license": "MIT"
},
"node_modules/tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
@ -5577,7 +5980,6 @@
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true,
"license": "0BSD"
},
"node_modules/turbo-stream": {
@ -5672,6 +6074,15 @@
"punycode": "^2.1.0"
}
},
"node_modules/use-sync-external-store": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz",
"integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==",
"license": "MIT",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",

View File

@ -10,6 +10,9 @@
"license": "ISC",
"description": "",
"dependencies": {
"@base-ui-components/react": "^1.0.0-alpha.5",
"@bem-react/classname": "^1.6.0",
"@bem-react/classnames": "^1.3.10",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@mui/material": "^6.4.1",

View File

@ -0,0 +1,7 @@
@use '../shared/styles/colors.scss' as *;
body {
background-color: $background;
color: $text;
caret-color: $secondary;
}

View File

@ -1,15 +1,22 @@
import React from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import { ThemeProvider } from '@mui/material';
import { Root } from '../pages/root';
import { Search } from '../pages/search';
import theme from '../features/theme';
import './normalize.css';
import './app.scss';
export const App: React.FC = () => {
return (
<ThemeProvider theme={theme}>
<BrowserRouter>
<Routes>
<Route path='/search' element={<Search />} />
<Route path='/' element={<Root />} />
</Routes>
</BrowserRouter>
</ThemeProvider>
);
};

349
frontend/src/app/normalize.css vendored Normal file
View File

@ -0,0 +1,349 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}

View File

@ -1,8 +1,14 @@
export type DBRecord = {
export type Record = {
description: string | null,
weight: number | null,
calspergram: number | null,
calories: number | null,
};
export type DBRecord = Metadata & Record;
type Metadata = {
id: number,
date: Date,
description: string,
weight: number,
calories: number,
calspergram: number
};
owner: string,
}

View File

@ -0,0 +1,14 @@
@use "../../shared/styles/colors.scss" as *;
.CreateRecord {
margin: auto;
padding: 15px;
border: 1px solid $secondary;
border-radius: 10px;
max-width: 600px;
&-Options {
display: flex;
justify-content: end;
}
}

View File

@ -1,8 +1,150 @@
import React from 'react'
import { TextareaAutosize } from '@mui/material'
import React, { useState } from 'react';
import { Box, Button, InputAdornment, TextField } from '@mui/material';
import { cn } from '@bem-react/classname';
import './createRecord.scss';
import { save } from './server';
const name = cn('CreateRecord');
export const CreateRecord: React.FC = () => {
const [weight, setWeight] = useState('');
const [cpg, setCPG] = useState('');
const [cals, setCals] = useState('');
const [description, setDescription] = useState('');
const [errors, setErrors] = useState({weight: false, cpg: false, cals: false});
const submit = () => {
// Validation
if (isNaN(Number(weight)) && weight != '') {
setErrors(e => ({...e, weight: true}));
}
if (isNaN(Number(cpg)) && cpg != '') {
setErrors(e => ({...e, cpg: true}));
}
if (isNaN(Number(cals)) && cals != '') {
setErrors(e => ({...e, cals: true}));
}
if (errors.cals || errors.cpg || errors.weight) {
return;
}
if (weight == '' && cpg == '' && cals == '') {
setErrors(e => ({...e, cals: true}));
}
if (weight != '' && cpg == '' && cals == '') {
setErrors(e => ({...e, cpg: true}));
}
if (weight == '' && cpg != '' && cals == '') {
setErrors(e => ({...e, weight: true}));
}
if (errors.cals || errors.cpg || errors.weight) {
return;
}
let record;
save({
calories: Number(cals) || Number(weight) * Number(cpg),
calspergram: Number(cpg) || null,
description: description || null,
weight: Number(weight) || null,
}).then(() => {
setWeight('');
setCPG('');
setCals('');
});
}
return (
<TextareaAutosize />
<div className={name()}>
<Box
sx={{
display: 'flex',
flexDirection: 'row',
gap: 2, // Adjust spacing between inputs
alignItems: 'center', // Align items vertically
flexWrap: 'wrap' // Ensure it wraps on smaller screens
}}
>
<TextField
fullWidth
error={errors.weight}
value={weight}
onChange={e => {
setWeight(e.target.value);
setErrors(e => ({...e, weight: false}))
}}
variant='outlined'
label='Weight'
size='small'
sx={{ flex: 1, minWidth: '15ch' }}
slotProps={{
input: {
endAdornment: <InputAdornment position="end">g</InputAdornment>,
},
}}
/>
<TextField
error={errors.cpg}
value={cpg}
onChange={e => {
setCPG(e.target.value);
setErrors(e => ({...e, cpg: false}));
}}
variant='outlined'
label='Cals per gramm'
size='small'
sx={{ flex: 1, minWidth: '15ch' }}
slotProps={{
input: {
endAdornment: <InputAdornment position="end">cals</InputAdornment>,
},
}}
/>
<TextField
error={errors.cals}
value={cals}
onChange={e => {
setCals(e.target.value);
setErrors(e => ({...e, cals: false}));
}}
variant='outlined'
label='Calories'
size='small'
sx={{ flex: 1, minWidth: '15ch' }}
slotProps={{
input: {
endAdornment: <InputAdornment position="end">cals</InputAdornment>,
},
}}
/>
</Box>
<TextField
value={description}
onChange={e => setDescription(e.target.value)}
variant='standard'
fullWidth
placeholder='Description'
size='small'
margin='normal'
/>
<div className={name('Options')}>
<Button
onClick={submit}
variant='contained'
>
Save
</Button>
</div>
</div>
)
}

View File

@ -0,0 +1,5 @@
import { Record } from '../../entities/record';
export async function save(record: Record) {
console.log(record);
}

View File

@ -0,0 +1,83 @@
import { createTheme } from "@mui/material/styles";
const theme = createTheme({
palette: {
mode: "dark", // Ensures proper dark mode behavior
background: {
default: "#121212",
paper: "#181818",
},
primary: {
main: "#009999", // Accent Positive
contrastText: "#f4f4f4", // Ensuring good contrast
},
secondary: {
main: "#444444",
contrastText: "#f4f4f4",
},
error: {
main: "#FF9640", // Accent Negative
},
text: {
primary: "#f4f4f4", // Main text color
secondary: "hsla(0,0%,100%,.5)", // Secondary text color
disabled: "rgba(255, 255, 255, 0.3)", // Lower contrast for disabled elements
},
divider: "rgba(255, 255, 255, 0.12)", // Subtle divider color for better UI separation
action: {
hover: "rgba(255, 255, 255, 0.08)",
selected: "rgba(255, 255, 255, 0.16)",
disabled: "rgba(255, 255, 255, 0.3)",
},
},
components: {
MuiPaper: {
styleOverrides: {
root: {
backgroundColor: "#181818",
color: "#f4f4f4",
},
},
},
MuiAppBar: {
styleOverrides: {
root: {
backgroundColor: "#181818",
},
},
},
MuiButton: {
styleOverrides: {
root: {
textTransform: "none",
borderRadius: "8px",
},
},
},
MuiTextField: {
styleOverrides: {
root: {
"& label": {
color: "hsla(0,0%,100%,.5)", // Label text color
},
"& label.Mui-focused": {
color: "#009999", // Focused label color
},
"& .MuiOutlinedInput-root": {
"& fieldset": {
borderColor: "#444444", // Default border color
},
"&:hover fieldset": {
borderColor: "#009999", // Border color on hover
},
"&.Mui-focused fieldset": {
borderColor: "#009999", // Border color when focused
},
},
},
},
},
},
});
export default theme;

View File

@ -1,10 +1,13 @@
import React from 'react';
import { CreateRecord } from '../features/createRecord';
import { Page } from '../shared/components/Page';
export const Root: React.FC = () => {
return (
<div>
<Page>
<CreateRecord />
</Page>
</div>
)
}

View File

@ -0,0 +1,12 @@
@use "../../../shared/styles/colors.scss" as *;
.Page {
background-color: $background-secondary;
height: 100%;
width: 80%;
margin: auto;
@media (max-width: 600px) {
width: 100%;
}
}

View File

@ -0,0 +1,18 @@
import { cn } from '@bem-react/classname'
import React, { JSX } from 'react'
import './Page.scss';
type Props = {
children: string | JSX.Element | JSX.Element[]
}
const name = cn('Page')
export const Page: React.FC<Props> = ({children}) => {
return (
<div className={name()}>
{children}
</div>
)
}

View File

@ -0,0 +1 @@
export * from './Page';

View File

@ -0,0 +1,7 @@
$background: #121212;
$background-secondary: #181818;
$secondary: gray;
$text: #f4f4f4;
$text-secondary: hsla(0,0%,100%,.5);
$accent-positive: #009999;
$accent-negative: #FF9640;

View File

@ -29,6 +29,16 @@ module.exports = {
}
]
},
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: { sourceMap: true }
}
]
},
],
},
resolve: {
@ -55,4 +65,9 @@ module.exports = {
}
})
],
performance: {
hints: false,
maxEntrypointSize: 512000,
maxAssetSize: 512000
},
};