Migrate PocketBase to new version (#863)
This commit is contained in:
parent
1879c335c3
commit
84e59b10d1
|
@ -20,7 +20,7 @@
|
||||||
"mlg-converter": "^0.7.1",
|
"mlg-converter": "^0.7.1",
|
||||||
"nanoid": "^4.0.0",
|
"nanoid": "^4.0.0",
|
||||||
"pako": "^2.0.4",
|
"pako": "^2.0.4",
|
||||||
"pocketbase": "^0.7.4",
|
"pocketbase": "^0.8.0-rc1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-ga4": "^1.4.1",
|
"react-ga4": "^1.4.1",
|
||||||
|
@ -1887,6 +1887,18 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@eslint/eslintrc/node_modules/type-fest": {
|
||||||
|
"version": "0.20.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||||
|
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@gar/promisify": {
|
"node_modules/@gar/promisify": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
|
||||||
|
@ -1895,14 +1907,14 @@
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/config-array": {
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
"version": "0.11.6",
|
"version": "0.11.7",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.6.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz",
|
||||||
"integrity": "sha512-jJr+hPTJYKyDILJfhNSHsjiwXYf26Flsz8DvNndOsHs5pwSnpGUEy8yzF0JYhCEvTDdV2vuOK5tt8BVhwO5/hg==",
|
"integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@humanwhocodes/object-schema": "^1.2.1",
|
"@humanwhocodes/object-schema": "^1.2.1",
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.1.1",
|
||||||
"minimatch": "^3.0.4"
|
"minimatch": "^3.0.5"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.10.0"
|
"node": ">=10.10.0"
|
||||||
|
@ -2461,6 +2473,18 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@hyper-tuner/eslint-config/node_modules/type-fest": {
|
||||||
|
"version": "0.20.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||||
|
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@hyper-tuner/ini": {
|
"node_modules/@hyper-tuner/ini": {
|
||||||
"version": "0.6.2",
|
"version": "0.6.2",
|
||||||
"resolved": "https://npm.pkg.github.com/download/@hyper-tuner/ini/0.6.2/fbca9ad490d805b93c1ce705ef9d2aee103498e7",
|
"resolved": "https://npm.pkg.github.com/download/@hyper-tuner/ini/0.6.2/fbca9ad490d805b93c1ce705ef9d2aee103498e7",
|
||||||
|
@ -4107,9 +4131,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001426",
|
"version": "1.0.30001427",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001426.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001427.tgz",
|
||||||
"integrity": "sha512-n7cosrHLl8AWt0wwZw/PJZgUg3lV0gk9LMI7ikGJwhyhgsd2Nb65vKvmSexCqq/J7rbH3mFG6yZZiPR5dLPW5A==",
|
"integrity": "sha512-lfXQ73oB9c8DP5Suxaszm+Ta2sr/4tf8+381GkIm1MLj/YdLf+rEDyDSRCzeltuyTVGm+/s18gdZ0q+Wmp8VsQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -5708,6 +5732,18 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint/node_modules/type-fest": {
|
||||||
|
"version": "0.20.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||||
|
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/espree": {
|
"node_modules/espree": {
|
||||||
"version": "9.4.0",
|
"version": "9.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz",
|
||||||
|
@ -8622,9 +8658,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pocketbase": {
|
"node_modules/pocketbase": {
|
||||||
"version": "0.7.4",
|
"version": "0.8.0-rc1",
|
||||||
"resolved": "https://registry.npmjs.org/pocketbase/-/pocketbase-0.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/pocketbase/-/pocketbase-0.8.0-rc1.tgz",
|
||||||
"integrity": "sha512-PvBRi4hbgbiBwDjhHa9lGD/ala8dSTjKeNAsHAgsXdIo4v9RgCk2s3Zqd/4UXVBgTJHVM6F7fGOZPvvJfSNVLQ=="
|
"integrity": "sha512-PXY2d0Em639n0WlixAhUtpsUH8At7S2VH0eqPWU0Ouiv7NwJLFFNTIE1IQL9F/cEJZF9BGb6FIYZqb/I4Fj4Iw=="
|
||||||
},
|
},
|
||||||
"node_modules/pocketbase-typegen": {
|
"node_modules/pocketbase-typegen": {
|
||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
|
@ -10511,18 +10547,6 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tempy/node_modules/type-fest": {
|
|
||||||
"version": "0.16.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz",
|
|
||||||
"integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/terser": {
|
"node_modules/terser": {
|
||||||
"version": "5.15.1",
|
"version": "5.15.1",
|
||||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
|
||||||
|
@ -10670,9 +10694,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/type-fest": {
|
"node_modules/type-fest": {
|
||||||
"version": "0.20.2",
|
"version": "0.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz",
|
||||||
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
"integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
|
@ -12832,6 +12856,12 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"type-fest": "^0.20.2"
|
"type-fest": "^0.20.2"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"type-fest": {
|
||||||
|
"version": "0.20.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||||
|
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||||
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -12843,14 +12873,14 @@
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@humanwhocodes/config-array": {
|
"@humanwhocodes/config-array": {
|
||||||
"version": "0.11.6",
|
"version": "0.11.7",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.6.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz",
|
||||||
"integrity": "sha512-jJr+hPTJYKyDILJfhNSHsjiwXYf26Flsz8DvNndOsHs5pwSnpGUEy8yzF0JYhCEvTDdV2vuOK5tt8BVhwO5/hg==",
|
"integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@humanwhocodes/object-schema": "^1.2.1",
|
"@humanwhocodes/object-schema": "^1.2.1",
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.1.1",
|
||||||
"minimatch": "^3.0.4"
|
"minimatch": "^3.0.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@humanwhocodes/module-importer": {
|
"@humanwhocodes/module-importer": {
|
||||||
|
@ -13221,6 +13251,12 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"has-flag": "^4.0.0"
|
"has-flag": "^4.0.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"type-fest": {
|
||||||
|
"version": "0.20.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||||
|
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||||
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -14467,9 +14503,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"caniuse-lite": {
|
"caniuse-lite": {
|
||||||
"version": "1.0.30001426",
|
"version": "1.0.30001427",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001426.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001427.tgz",
|
||||||
"integrity": "sha512-n7cosrHLl8AWt0wwZw/PJZgUg3lV0gk9LMI7ikGJwhyhgsd2Nb65vKvmSexCqq/J7rbH3mFG6yZZiPR5dLPW5A==",
|
"integrity": "sha512-lfXQ73oB9c8DP5Suxaszm+Ta2sr/4tf8+381GkIm1MLj/YdLf+rEDyDSRCzeltuyTVGm+/s18gdZ0q+Wmp8VsQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"chalk": {
|
"chalk": {
|
||||||
|
@ -15294,6 +15330,12 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"has-flag": "^4.0.0"
|
"has-flag": "^4.0.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"type-fest": {
|
||||||
|
"version": "0.20.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||||
|
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||||
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -17642,9 +17684,9 @@
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"pocketbase": {
|
"pocketbase": {
|
||||||
"version": "0.7.4",
|
"version": "0.8.0-rc1",
|
||||||
"resolved": "https://registry.npmjs.org/pocketbase/-/pocketbase-0.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/pocketbase/-/pocketbase-0.8.0-rc1.tgz",
|
||||||
"integrity": "sha512-PvBRi4hbgbiBwDjhHa9lGD/ala8dSTjKeNAsHAgsXdIo4v9RgCk2s3Zqd/4UXVBgTJHVM6F7fGOZPvvJfSNVLQ=="
|
"integrity": "sha512-PXY2d0Em639n0WlixAhUtpsUH8At7S2VH0eqPWU0Ouiv7NwJLFFNTIE1IQL9F/cEJZF9BGb6FIYZqb/I4Fj4Iw=="
|
||||||
},
|
},
|
||||||
"pocketbase-typegen": {
|
"pocketbase-typegen": {
|
||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
|
@ -18982,14 +19024,6 @@
|
||||||
"temp-dir": "^2.0.0",
|
"temp-dir": "^2.0.0",
|
||||||
"type-fest": "^0.16.0",
|
"type-fest": "^0.16.0",
|
||||||
"unique-string": "^2.0.0"
|
"unique-string": "^2.0.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"type-fest": {
|
|
||||||
"version": "0.16.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz",
|
|
||||||
"integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"terser": {
|
"terser": {
|
||||||
|
@ -19111,9 +19145,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"type-fest": {
|
"type-fest": {
|
||||||
"version": "0.20.2",
|
"version": "0.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz",
|
||||||
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
"integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
"mlg-converter": "^0.7.1",
|
"mlg-converter": "^0.7.1",
|
||||||
"nanoid": "^4.0.0",
|
"nanoid": "^4.0.0",
|
||||||
"pako": "^2.0.4",
|
"pako": "^2.0.4",
|
||||||
"pocketbase": "^0.7.4",
|
"pocketbase": "^0.8.0-rc1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-ga4": "^1.4.1",
|
"react-ga4": "^1.4.1",
|
||||||
|
|
|
@ -10,14 +10,14 @@ export type BaseRecord = {
|
||||||
id: RecordIdString
|
id: RecordIdString
|
||||||
created: IsoDateString
|
created: IsoDateString
|
||||||
updated: IsoDateString
|
updated: IsoDateString
|
||||||
'@collectionId': string
|
collectionId: string
|
||||||
'@collectionName': string
|
collectionName: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum Collections {
|
export enum Collections {
|
||||||
IniFiles = 'iniFiles',
|
IniFiles = 'iniFiles',
|
||||||
Profiles = 'profiles',
|
|
||||||
Tunes = 'tunes',
|
Tunes = 'tunes',
|
||||||
|
Users = 'users',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type IniFilesRecord = {
|
export type IniFilesRecord = {
|
||||||
|
@ -26,15 +26,8 @@ export type IniFilesRecord = {
|
||||||
ecosystem: 'speeduino' | 'rusefi'
|
ecosystem: 'speeduino' | 'rusefi'
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProfilesRecord = {
|
|
||||||
userId: UserIdString
|
|
||||||
username: string
|
|
||||||
avatar?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TunesRecord = {
|
export type TunesRecord = {
|
||||||
user: UserIdString
|
author: RecordIdString
|
||||||
userProfile: RecordIdString
|
|
||||||
tuneId: string
|
tuneId: string
|
||||||
signature: string
|
signature: string
|
||||||
vehicleName: string
|
vehicleName: string
|
||||||
|
@ -59,8 +52,12 @@ export type TunesRecord = {
|
||||||
toothLogFiles?: string[]
|
toothLogFiles?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type UsersRecord = {
|
||||||
|
avatar?: string
|
||||||
|
}
|
||||||
|
|
||||||
export type CollectionRecords = {
|
export type CollectionRecords = {
|
||||||
iniFiles: IniFilesRecord
|
iniFiles: IniFilesRecord
|
||||||
profiles: ProfilesRecord
|
|
||||||
tunes: TunesRecord
|
tunes: TunesRecord
|
||||||
|
users: UsersRecord
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,11 @@ import {
|
||||||
import {
|
import {
|
||||||
client,
|
client,
|
||||||
formatError,
|
formatError,
|
||||||
User,
|
|
||||||
} from '../pocketbase';
|
} from '../pocketbase';
|
||||||
import { buildRedirectUrl } from '../utils/url';
|
import { buildRedirectUrl } from '../utils/url';
|
||||||
import { Collections } from '../@types/pocketbase-types';
|
import { Collections } from '../@types/pocketbase-types';
|
||||||
import { Routes } from '../routes';
|
import { Routes } from '../routes';
|
||||||
|
import { UsersRecordFull } from '../types/dbData';
|
||||||
|
|
||||||
// TODO: this should be imported from pocketbase but currently is not exported
|
// TODO: this should be imported from pocketbase but currently is not exported
|
||||||
export type AuthProviderInfo = {
|
export type AuthProviderInfo = {
|
||||||
|
@ -39,10 +39,10 @@ export enum OAuthProviders {
|
||||||
};
|
};
|
||||||
|
|
||||||
interface AuthValue {
|
interface AuthValue {
|
||||||
currentUser: User | null,
|
currentUser: UsersRecordFull | null,
|
||||||
signUp: (email: string, password: string) => Promise<User>,
|
signUp: (email: string, password: string, username: string) => Promise<UsersRecordFull>,
|
||||||
login: (email: string, password: string) => Promise<User>,
|
login: (email: string, password: string) => Promise<UsersRecordFull>,
|
||||||
refreshUser: () => Promise<User | null>,
|
refreshUser: () => Promise<UsersRecordFull | null>,
|
||||||
sendEmailVerification: () => Promise<void>,
|
sendEmailVerification: () => Promise<void>,
|
||||||
confirmEmailVerification: (token: string) => Promise<void>,
|
confirmEmailVerification: (token: string) => Promise<void>,
|
||||||
confirmResetPassword: (token: string, password: string) => Promise<void>,
|
confirmResetPassword: (token: string, password: string) => Promise<void>,
|
||||||
|
@ -57,21 +57,24 @@ const AuthContext = createContext<AuthValue | null>(null);
|
||||||
|
|
||||||
const useAuth = () => useContext<AuthValue>(AuthContext as any);
|
const useAuth = () => useContext<AuthValue>(AuthContext as any);
|
||||||
|
|
||||||
|
const users = client.collection(Collections.Users);
|
||||||
|
|
||||||
const AuthProvider = (props: { children: ReactNode }) => {
|
const AuthProvider = (props: { children: ReactNode }) => {
|
||||||
const { children } = props;
|
const { children } = props;
|
||||||
const [currentUser, setCurrentUser] = useState<User | null>(null);
|
const [currentUser, setCurrentUser] = useState<UsersRecordFull | null>(null);
|
||||||
|
|
||||||
const value = useMemo(() => ({
|
const value = useMemo(() => ({
|
||||||
currentUser,
|
currentUser,
|
||||||
signUp: async (email: string, password: string) => {
|
signUp: async (email: string, password: string, username: string) => {
|
||||||
try {
|
try {
|
||||||
const user = await client.users.create({
|
const user = await users.create({
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
passwordConfirm: password,
|
passwordConfirm: password,
|
||||||
|
username,
|
||||||
});
|
});
|
||||||
client.users.requestVerification(user.email);
|
users.requestVerification(email);
|
||||||
await client.users.authViaEmail(user.email, password);
|
await users.authWithPassword(email, password);
|
||||||
|
|
||||||
return Promise.resolve(user);
|
return Promise.resolve(user);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -80,16 +83,16 @@ const AuthProvider = (props: { children: ReactNode }) => {
|
||||||
},
|
},
|
||||||
login: async (email: string, password: string) => {
|
login: async (email: string, password: string) => {
|
||||||
try {
|
try {
|
||||||
const authResponse = await client.users.authViaEmail(email, password);
|
const authResponse = await users.authWithPassword(email, password);
|
||||||
return Promise.resolve(authResponse.user);
|
return Promise.resolve(authResponse.record);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return Promise.reject(new Error(formatError(error)));
|
return Promise.reject(new Error(formatError(error)));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
refreshUser: async () => {
|
refreshUser: async () => {
|
||||||
try {
|
try {
|
||||||
const authResponse = await client.users.refresh();
|
const authResponse = await users.authRefresh();
|
||||||
return Promise.resolve(authResponse.user);
|
return Promise.resolve(authResponse.record);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
client.authStore.clear();
|
client.authStore.clear();
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
|
@ -97,7 +100,7 @@ const AuthProvider = (props: { children: ReactNode }) => {
|
||||||
},
|
},
|
||||||
sendEmailVerification: async () => {
|
sendEmailVerification: async () => {
|
||||||
try {
|
try {
|
||||||
await client.users.requestVerification(currentUser!.email);
|
await users.requestVerification(currentUser!.email);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return Promise.reject(new Error(formatError(error)));
|
return Promise.reject(new Error(formatError(error)));
|
||||||
|
@ -105,7 +108,7 @@ const AuthProvider = (props: { children: ReactNode }) => {
|
||||||
},
|
},
|
||||||
confirmEmailVerification: async (token: string) => {
|
confirmEmailVerification: async (token: string) => {
|
||||||
try {
|
try {
|
||||||
await client.users.confirmVerification(token);
|
await users.confirmVerification(token);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return Promise.reject(new Error(formatError(error)));
|
return Promise.reject(new Error(formatError(error)));
|
||||||
|
@ -113,7 +116,7 @@ const AuthProvider = (props: { children: ReactNode }) => {
|
||||||
},
|
},
|
||||||
confirmResetPassword: async (token: string, password: string) => {
|
confirmResetPassword: async (token: string, password: string) => {
|
||||||
try {
|
try {
|
||||||
await client.users.confirmPasswordReset(token, password, password);
|
await users.confirmPasswordReset(token, password, password);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return Promise.reject(new Error(formatError(error)));
|
return Promise.reject(new Error(formatError(error)));
|
||||||
|
@ -124,7 +127,7 @@ const AuthProvider = (props: { children: ReactNode }) => {
|
||||||
},
|
},
|
||||||
initResetPassword: async (email: string) => {
|
initResetPassword: async (email: string) => {
|
||||||
try {
|
try {
|
||||||
await client.users.requestPasswordReset(email);
|
await users.requestPasswordReset(email);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return Promise.reject(new Error(formatError(error)));
|
return Promise.reject(new Error(formatError(error)));
|
||||||
|
@ -132,14 +135,14 @@ const AuthProvider = (props: { children: ReactNode }) => {
|
||||||
},
|
},
|
||||||
listAuthMethods: async () => {
|
listAuthMethods: async () => {
|
||||||
try {
|
try {
|
||||||
const methods = await client.users.listAuthMethods();
|
const methods = await users.listAuthMethods();
|
||||||
return Promise.resolve(methods);
|
return Promise.resolve(methods);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return Promise.reject(new Error(formatError(error)));
|
return Promise.reject(new Error(formatError(error)));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
oAuth: async (provider: OAuthProviders, code: string, codeVerifier: string) => {
|
oAuth: async (provider: OAuthProviders, code: string, codeVerifier: string) => {
|
||||||
client.users.authViaOAuth2(
|
users.authWithOAuth2(
|
||||||
provider,
|
provider,
|
||||||
code,
|
code,
|
||||||
codeVerifier,
|
codeVerifier,
|
||||||
|
@ -148,7 +151,7 @@ const AuthProvider = (props: { children: ReactNode }) => {
|
||||||
},
|
},
|
||||||
updateUsername: async (username: string) => {
|
updateUsername: async (username: string) => {
|
||||||
try {
|
try {
|
||||||
await client.records.update(Collections.Profiles, currentUser!.profile!.id, {
|
await client.collection(Collections.Users).update(currentUser!.id, {
|
||||||
username,
|
username,
|
||||||
});
|
});
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
|
@ -159,24 +162,14 @@ const AuthProvider = (props: { children: ReactNode }) => {
|
||||||
}), [currentUser]);
|
}), [currentUser]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCurrentUser(client.authStore.model as User | null);
|
setCurrentUser(client.authStore.model as UsersRecordFull | null);
|
||||||
|
|
||||||
const storeUnsubscribe = client.authStore.onChange((_token, model) => {
|
const storeUnsubscribe = client.authStore.onChange((_token, model) => {
|
||||||
setCurrentUser(model as User | null);
|
setCurrentUser(model as UsersRecordFull | null);
|
||||||
});
|
|
||||||
|
|
||||||
client.realtime.subscribe(Collections.Tunes, (event) => {
|
|
||||||
console.info('Tunes event', event);
|
|
||||||
});
|
|
||||||
|
|
||||||
client.realtime.subscribe(Collections.Profiles, (event) => {
|
|
||||||
console.info('Profiles event', event);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
storeUnsubscribe();
|
storeUnsubscribe();
|
||||||
client.realtime.unsubscribe(Collections.Tunes);
|
|
||||||
client.realtime.unsubscribe(Collections.Profiles);
|
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,13 @@ import {
|
||||||
TunesRecord,
|
TunesRecord,
|
||||||
} from '../@types/pocketbase-types';
|
} from '../@types/pocketbase-types';
|
||||||
|
|
||||||
|
const tunesCollection = client.collection(Collections.Tunes);
|
||||||
|
const iniFilesCollection = client.collection(Collections.IniFiles);
|
||||||
|
|
||||||
const useDb = () => {
|
const useDb = () => {
|
||||||
const updateTune = async (id: string, data: TunesRecordPartial) => {
|
const updateTune = async (id: string, data: TunesRecordPartial) => {
|
||||||
try {
|
try {
|
||||||
await client.records.update(Collections.Tunes, id, data);
|
await tunesCollection.update(id, data);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Sentry.captureException(error);
|
Sentry.captureException(error);
|
||||||
|
@ -30,7 +33,7 @@ const useDb = () => {
|
||||||
|
|
||||||
const createTune = async (data: TunesRecord) => {
|
const createTune = async (data: TunesRecord) => {
|
||||||
try {
|
try {
|
||||||
const record = await client.records.create(Collections.Tunes, data);
|
const record = await tunesCollection.create(data);
|
||||||
|
|
||||||
return Promise.resolve(record as TunesRecordFull);
|
return Promise.resolve(record as TunesRecordFull);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -43,17 +46,23 @@ const useDb = () => {
|
||||||
|
|
||||||
const getTune = async (tuneId: string) => {
|
const getTune = async (tuneId: string) => {
|
||||||
try {
|
try {
|
||||||
const tune = await client.records.getList(Collections.Tunes, 1, 1, {
|
const tune = await tunesCollection.getFirstListItem(
|
||||||
filter: `tuneId = "${tuneId}"`,
|
`tuneId = "${tuneId}"`,
|
||||||
expand: 'userProfile',
|
{
|
||||||
});
|
expand: 'author',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
return Promise.resolve(tune.totalItems > 0 ? tune.items[0] as TunesRecordFull : null);
|
return Promise.resolve(tune as TunesRecordFull);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if ((error as ClientResponseError).isAbort) {
|
if ((error as ClientResponseError).isAbort) {
|
||||||
return Promise.reject(new Error('Cancelled'));
|
return Promise.reject(new Error('Cancelled'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((error as ClientResponseError).status === 404) {
|
||||||
|
return Promise.resolve(null);
|
||||||
|
}
|
||||||
|
|
||||||
Sentry.captureException(error);
|
Sentry.captureException(error);
|
||||||
databaseGenericError(new Error(formatError(error)));
|
databaseGenericError(new Error(formatError(error)));
|
||||||
|
|
||||||
|
@ -63,16 +72,18 @@ const useDb = () => {
|
||||||
|
|
||||||
const getIni = async (signature: string) => {
|
const getIni = async (signature: string) => {
|
||||||
try {
|
try {
|
||||||
const tune = await client.records.getList(Collections.IniFiles, 1, 1, {
|
const ini = await iniFilesCollection.getFirstListItem(`signature = "${signature}"`);
|
||||||
filter: `signature = "${signature}"`,
|
|
||||||
});
|
|
||||||
|
|
||||||
return Promise.resolve(tune.totalItems > 0 ? tune.items[0] as IniFilesRecordFull : null);
|
return Promise.resolve(ini as IniFilesRecordFull);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if ((error as ClientResponseError).isAbort) {
|
if ((error as ClientResponseError).isAbort) {
|
||||||
return Promise.reject(new Error('Cancelled'));
|
return Promise.reject(new Error('Cancelled'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((error as ClientResponseError).status === 404) {
|
||||||
|
return Promise.resolve(null);
|
||||||
|
}
|
||||||
|
|
||||||
Sentry.captureException(error);
|
Sentry.captureException(error);
|
||||||
databaseGenericError(new Error(formatError(error)));
|
databaseGenericError(new Error(formatError(error)));
|
||||||
|
|
||||||
|
@ -88,10 +99,10 @@ const useDb = () => {
|
||||||
.join(' || ');
|
.join(' || ');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const list = await client.records.getList(Collections.Tunes, page, perPage, {
|
const list = await tunesCollection.getList(page, perPage, {
|
||||||
sort: '-updated',
|
sort: '-updated',
|
||||||
filter,
|
filter,
|
||||||
expand: 'userProfile',
|
expand: 'author',
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
|
@ -112,7 +123,7 @@ const useDb = () => {
|
||||||
|
|
||||||
const autocomplete = async (attribute: string, search: string) => {
|
const autocomplete = async (attribute: string, search: string) => {
|
||||||
try {
|
try {
|
||||||
const items = await client.records.getFullList(Collections.Tunes, 10, {
|
const items = await tunesCollection.getFullList(10, {
|
||||||
filter: `${attribute} ~ "${search}"`,
|
filter: `${attribute} ~ "${search}"`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,12 @@ import {
|
||||||
copyToClipboard,
|
copyToClipboard,
|
||||||
isClipboardSupported,
|
isClipboardSupported,
|
||||||
} from '../utils/clipboard';
|
} from '../utils/clipboard';
|
||||||
import { ProfilesRecord } from '../@types/pocketbase-types';
|
|
||||||
import { isEscape } from '../utils/keyboard/shortcuts';
|
import { isEscape } from '../utils/keyboard/shortcuts';
|
||||||
import { TunesRecordFull } from '../types/dbData';
|
import {
|
||||||
import { formatTime } from '../pocketbase';
|
TunesRecordFull,
|
||||||
|
UsersRecordFull,
|
||||||
|
} from '../types/dbData';
|
||||||
|
import { formatTime } from '../utils/time';
|
||||||
|
|
||||||
const { useBreakpoint } = Grid;
|
const { useBreakpoint } = Grid;
|
||||||
const { Text, Title } = Typography;
|
const { Text, Title } = Typography;
|
||||||
|
@ -64,7 +66,7 @@ const Hub = () => {
|
||||||
...tune,
|
...tune,
|
||||||
key: tune.tuneId,
|
key: tune.tuneId,
|
||||||
year: tune.year,
|
year: tune.year,
|
||||||
author: (tune['@expand'] as { userProfile: ProfilesRecord }).userProfile.username,
|
author: (tune.expand.author as unknown as UsersRecordFull).username,
|
||||||
displacement: `${tune.displacement}l`,
|
displacement: `${tune.displacement}l`,
|
||||||
aspiration: aspirationMapper[tune.aspiration],
|
aspiration: aspirationMapper[tune.aspiration],
|
||||||
published: formatTime(tune.updated),
|
published: formatTime(tune.updated),
|
||||||
|
|
|
@ -21,7 +21,8 @@ import {
|
||||||
import Loader from '../components/Loader';
|
import Loader from '../components/Loader';
|
||||||
import { Routes } from '../routes';
|
import { Routes } from '../routes';
|
||||||
import { useAuth } from '../contexts/AuthContext';
|
import { useAuth } from '../contexts/AuthContext';
|
||||||
import { formatTime } from '../pocketbase';
|
import { formatTime } from '../utils/time';
|
||||||
|
import { UsersRecordFull } from '../types/dbData';
|
||||||
|
|
||||||
const { Item } = Form;
|
const { Item } = Form;
|
||||||
const rowProps = { gutter: 10 };
|
const rowProps = { gutter: 10 };
|
||||||
|
@ -39,7 +40,7 @@ const Info = ({ tuneData }: { tuneData: TuneDataState }) => {
|
||||||
tuneId: tuneData.tuneId,
|
tuneId: tuneData.tuneId,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const canManage = currentUser && tuneData && currentUser.id === tuneData.user;
|
const canManage = currentUser && tuneData && currentUser.id === tuneData.author;
|
||||||
|
|
||||||
const manageSection = (
|
const manageSection = (
|
||||||
<>
|
<>
|
||||||
|
@ -70,7 +71,7 @@ const Info = ({ tuneData }: { tuneData: TuneDataState }) => {
|
||||||
<Row {...rowProps}>
|
<Row {...rowProps}>
|
||||||
<Col {...colProps}>
|
<Col {...colProps}>
|
||||||
<Item>
|
<Item>
|
||||||
<Input value={tuneData['@expand'].userProfile.username} addonBefore="Author" />
|
<Input value={(tuneData.expand.author as unknown as UsersRecordFull).username} addonBefore="Author" />
|
||||||
</Item>
|
</Item>
|
||||||
</Col>
|
</Col>
|
||||||
<Col {...colProps}>
|
<Col {...colProps}>
|
||||||
|
|
|
@ -50,7 +50,6 @@ import {
|
||||||
error,
|
error,
|
||||||
restrictedPage,
|
restrictedPage,
|
||||||
signatureNotSupportedWarning,
|
signatureNotSupportedWarning,
|
||||||
usernameNotSet,
|
|
||||||
} from './auth/notifications';
|
} from './auth/notifications';
|
||||||
import { useAuth } from '../contexts/AuthContext';
|
import { useAuth } from '../contexts/AuthContext';
|
||||||
import { Routes } from '../routes';
|
import { Routes } from '../routes';
|
||||||
|
@ -211,8 +210,7 @@ const UploadPage = () => {
|
||||||
const { signature } = tuneParser.parse(await tuneFile!.arrayBuffer()).getTune().details;
|
const { signature } = tuneParser.parse(await tuneFile!.arrayBuffer()).getTune().details;
|
||||||
|
|
||||||
const newData: TunesRecord = {
|
const newData: TunesRecord = {
|
||||||
user: currentUser!.id,
|
author: currentUser!.id,
|
||||||
userProfile: currentUser!.profile!.id,
|
|
||||||
tuneId: newTuneId!,
|
tuneId: newTuneId!,
|
||||||
signature,
|
signature,
|
||||||
vehicleName,
|
vehicleName,
|
||||||
|
@ -434,7 +432,7 @@ const UploadPage = () => {
|
||||||
|
|
||||||
if (oldTune) {
|
if (oldTune) {
|
||||||
// this is someone elses tune
|
// this is someone elses tune
|
||||||
if (oldTune.user !== currentUser?.id) {
|
if (oldTune.author !== currentUser?.id) {
|
||||||
navigateToNewTuneId();
|
navigateToNewTuneId();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -533,13 +531,6 @@ const UploadPage = () => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((user.profile?.username?.length || 0) === 0) {
|
|
||||||
usernameNotSet();
|
|
||||||
navigate(Routes.PROFILE);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsUserAuthorized(true);
|
setIsUserAuthorized(true);
|
||||||
prepareData();
|
prepareData();
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {
|
||||||
GithubOutlined,
|
GithubOutlined,
|
||||||
FacebookOutlined,
|
FacebookOutlined,
|
||||||
UserAddOutlined,
|
UserAddOutlined,
|
||||||
|
UserOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import {
|
import {
|
||||||
Link,
|
Link,
|
||||||
|
@ -40,6 +41,7 @@ import {
|
||||||
import {
|
import {
|
||||||
emailRules,
|
emailRules,
|
||||||
requiredRules,
|
requiredRules,
|
||||||
|
usernameRules,
|
||||||
} from '../../utils/form';
|
} from '../../utils/form';
|
||||||
import { buildRedirectUrl } from '../../utils/url';
|
import { buildRedirectUrl } from '../../utils/url';
|
||||||
|
|
||||||
|
@ -89,10 +91,10 @@ const Login = ({ formRole }: { formRole: FormRoles }) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const emailSignUp = async ({ email, password }: { email: string, password: string }) => {
|
const emailSignUp = async ({ email, password, username }: { email: string, password: string, username: string }) => {
|
||||||
setIsEmailLoading(true);
|
setIsEmailLoading(true);
|
||||||
try {
|
try {
|
||||||
const user = await signUp(email, password);
|
const user = await signUp(email, password, username);
|
||||||
signUpSuccessful();
|
signUpSuccessful();
|
||||||
|
|
||||||
if (!user.verified) {
|
if (!user.verified) {
|
||||||
|
@ -242,6 +244,17 @@ const Login = ({ formRole }: { formRole: FormRoles }) => {
|
||||||
disabled={isAnythingLoading}
|
disabled={isAnythingLoading}
|
||||||
/>
|
/>
|
||||||
</Item>
|
</Item>
|
||||||
|
{!isLogin && <Item
|
||||||
|
name="username"
|
||||||
|
rules={usernameRules}
|
||||||
|
hasFeedback
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
prefix={<UserOutlined />}
|
||||||
|
placeholder="Username"
|
||||||
|
autoComplete="name"
|
||||||
|
/>
|
||||||
|
</Item>}
|
||||||
<Item
|
<Item
|
||||||
name="password"
|
name="password"
|
||||||
rules={requiredRules}
|
rules={requiredRules}
|
||||||
|
|
|
@ -106,7 +106,6 @@ const Profile = () => {
|
||||||
</>)}
|
</>)}
|
||||||
<Divider>Your Profile</Divider>
|
<Divider>Your Profile</Divider>
|
||||||
<Space direction="vertical" style={{ width: '100%' }} size="large">
|
<Space direction="vertical" style={{ width: '100%' }} size="large">
|
||||||
{(currentUser?.profile?.username?.length || 0) === 0 && <Alert message="Remember to set your username!" type="error" showIcon />}
|
|
||||||
<Form
|
<Form
|
||||||
validateMessages={validateMessages}
|
validateMessages={validateMessages}
|
||||||
form={formProfile}
|
form={formProfile}
|
||||||
|
@ -114,11 +113,11 @@ const Profile = () => {
|
||||||
fields={[
|
fields={[
|
||||||
{
|
{
|
||||||
name: 'username',
|
name: 'username',
|
||||||
value: currentUser?.profile?.username,
|
value: currentUser!.username,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'email',
|
name: 'email',
|
||||||
value: currentUser?.email,
|
value: currentUser!.email,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
|
|
@ -19,12 +19,6 @@ const emailNotVerified = () => notification.warning({
|
||||||
...baseOptions,
|
...baseOptions,
|
||||||
});
|
});
|
||||||
|
|
||||||
const usernameNotSet = () => notification.warning({
|
|
||||||
message: 'Update your profile',
|
|
||||||
description: 'Your username has to be set before you can upload files!',
|
|
||||||
...baseOptions,
|
|
||||||
});
|
|
||||||
|
|
||||||
const signUpSuccessful = () => notification.success({
|
const signUpSuccessful = () => notification.success({
|
||||||
message: 'Sign Up successful',
|
message: 'Sign Up successful',
|
||||||
description: 'Welcome on board!',
|
description: 'Welcome on board!',
|
||||||
|
@ -156,7 +150,6 @@ const downloading = () => notification.success({
|
||||||
export {
|
export {
|
||||||
error,
|
error,
|
||||||
emailNotVerified,
|
emailNotVerified,
|
||||||
usernameNotSet,
|
|
||||||
signUpSuccessful,
|
signUpSuccessful,
|
||||||
signUpFailed,
|
signUpFailed,
|
||||||
logInSuccessful,
|
logInSuccessful,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import PocketBase, {
|
import PocketBase, {
|
||||||
ClientResponseError,
|
ClientResponseError,
|
||||||
User,
|
|
||||||
Record,
|
Record,
|
||||||
} from 'pocketbase';
|
} from 'pocketbase';
|
||||||
import { fetchEnv } from './utils/env';
|
import { fetchEnv } from './utils/env';
|
||||||
|
@ -23,16 +22,11 @@ const formatError = (error: any) => {
|
||||||
|
|
||||||
const removeFilenameSuffix = (filename: string) => filename.replace(/(.+)(_\w{10})(\.\w+)$/, '$1$3');
|
const removeFilenameSuffix = (filename: string) => filename.replace(/(.+)(_\w{10})(\.\w+)$/, '$1$3');
|
||||||
|
|
||||||
// NOTE: PocketBase doesn't return ISO time, this may change here: https://github.com/pocketbase/pocketbase/issues/376
|
|
||||||
const formatTime = (time: string) => new Date(`${time}Z`).toLocaleString();
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
API_URL,
|
API_URL,
|
||||||
client,
|
client,
|
||||||
formatError,
|
formatError,
|
||||||
formatTime,
|
|
||||||
removeFilenameSuffix,
|
removeFilenameSuffix,
|
||||||
ClientResponseError,
|
ClientResponseError,
|
||||||
User,
|
|
||||||
Record,
|
Record,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { Record } from '../pocketbase';
|
import { Record } from '../pocketbase';
|
||||||
import {
|
import {
|
||||||
IniFilesRecord,
|
IniFilesRecord,
|
||||||
ProfilesRecord,
|
|
||||||
TunesRecord,
|
TunesRecord,
|
||||||
|
UsersRecord,
|
||||||
} from '../@types/pocketbase-types';
|
} from '../@types/pocketbase-types';
|
||||||
|
|
||||||
type Partial<T> = {
|
type Partial<T> = {
|
||||||
|
@ -13,6 +13,6 @@ export type TunesRecordPartial = Partial<TunesRecord>;
|
||||||
|
|
||||||
export interface TunesRecordFull extends TunesRecord, Record { }
|
export interface TunesRecordFull extends TunesRecord, Record { }
|
||||||
|
|
||||||
export interface ProfilesRecordFull extends ProfilesRecord, Record { }
|
export interface UsersRecordFull extends UsersRecord, Record { }
|
||||||
|
|
||||||
export interface IniFilesRecordFull extends IniFilesRecord, Record { }
|
export interface IniFilesRecordFull extends IniFilesRecord, Record { }
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
|
export const formatTime = (time: string) => new Date(time).toLocaleString();
|
Loading…
Reference in New Issue