Merge pull request #36 from sambecker/auth-integration
Nav auth integration
This commit is contained in:
commit
756cbc7f1b
@ -17,10 +17,10 @@
|
|||||||
"@testing-library/react": "^14.1.2",
|
"@testing-library/react": "^14.1.2",
|
||||||
"@types/jest": "^29.5.11",
|
"@types/jest": "^29.5.11",
|
||||||
"@types/node": "^20.10.6",
|
"@types/node": "^20.10.6",
|
||||||
"@types/react": "18.2.46",
|
"@types/react": "18.2.47",
|
||||||
"@types/react-dom": "18.2.18",
|
"@types/react-dom": "18.2.18",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.17.0",
|
"@typescript-eslint/eslint-plugin": "^6.18.0",
|
||||||
"@typescript-eslint/parser": "^6.17.0",
|
"@typescript-eslint/parser": "^6.18.0",
|
||||||
"@vercel/analytics": "^1.1.1",
|
"@vercel/analytics": "^1.1.1",
|
||||||
"@vercel/blob": "^0.16.1",
|
"@vercel/blob": "^0.16.1",
|
||||||
"@vercel/postgres": "0.5.1",
|
"@vercel/postgres": "0.5.1",
|
||||||
@ -44,7 +44,7 @@
|
|||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-icons": "^4.12.0",
|
"react-icons": "^4.12.0",
|
||||||
"sonner": "^1.3.1",
|
"sonner": "^1.3.1",
|
||||||
"tailwindcss": "3.4.0",
|
"tailwindcss": "3.4.1",
|
||||||
"ts-exif-parser": "^0.2.2",
|
"ts-exif-parser": "^0.2.2",
|
||||||
"typescript": "5.3.3"
|
"typescript": "5.3.3"
|
||||||
}
|
}
|
||||||
|
|||||||
126
pnpm-lock.yaml
generated
126
pnpm-lock.yaml
generated
@ -16,7 +16,7 @@ dependencies:
|
|||||||
version: 14.0.4
|
version: 14.0.4
|
||||||
'@tailwindcss/forms':
|
'@tailwindcss/forms':
|
||||||
specifier: ^0.5.7
|
specifier: ^0.5.7
|
||||||
version: 0.5.7(tailwindcss@3.4.0)
|
version: 0.5.7(tailwindcss@3.4.1)
|
||||||
'@testing-library/jest-dom':
|
'@testing-library/jest-dom':
|
||||||
specifier: ^6.2.0
|
specifier: ^6.2.0
|
||||||
version: 6.2.0(@types/jest@29.5.11)(jest@29.7.0)
|
version: 6.2.0(@types/jest@29.5.11)(jest@29.7.0)
|
||||||
@ -30,17 +30,17 @@ dependencies:
|
|||||||
specifier: ^20.10.6
|
specifier: ^20.10.6
|
||||||
version: 20.10.6
|
version: 20.10.6
|
||||||
'@types/react':
|
'@types/react':
|
||||||
specifier: 18.2.46
|
specifier: 18.2.47
|
||||||
version: 18.2.46
|
version: 18.2.47
|
||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
specifier: 18.2.18
|
specifier: 18.2.18
|
||||||
version: 18.2.18
|
version: 18.2.18
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
specifier: ^6.17.0
|
specifier: ^6.18.0
|
||||||
version: 6.17.0(@typescript-eslint/parser@6.17.0)(eslint@8.56.0)(typescript@5.3.3)
|
version: 6.18.0(@typescript-eslint/parser@6.18.0)(eslint@8.56.0)(typescript@5.3.3)
|
||||||
'@typescript-eslint/parser':
|
'@typescript-eslint/parser':
|
||||||
specifier: ^6.17.0
|
specifier: ^6.18.0
|
||||||
version: 6.17.0(eslint@8.56.0)(typescript@5.3.3)
|
version: 6.18.0(eslint@8.56.0)(typescript@5.3.3)
|
||||||
'@vercel/analytics':
|
'@vercel/analytics':
|
||||||
specifier: ^1.1.1
|
specifier: ^1.1.1
|
||||||
version: 1.1.1
|
version: 1.1.1
|
||||||
@ -111,8 +111,8 @@ dependencies:
|
|||||||
specifier: ^1.3.1
|
specifier: ^1.3.1
|
||||||
version: 1.3.1(react-dom@18.2.0)(react@18.2.0)
|
version: 1.3.1(react-dom@18.2.0)(react@18.2.0)
|
||||||
tailwindcss:
|
tailwindcss:
|
||||||
specifier: 3.4.0
|
specifier: 3.4.1
|
||||||
version: 3.4.0
|
version: 3.4.1
|
||||||
ts-exif-parser:
|
ts-exif-parser:
|
||||||
specifier: ^0.2.2
|
specifier: ^0.2.2
|
||||||
version: 0.2.2
|
version: 0.2.2
|
||||||
@ -2118,13 +2118,13 @@ packages:
|
|||||||
tslib: 2.6.2
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@tailwindcss/forms@0.5.7(tailwindcss@3.4.0):
|
/@tailwindcss/forms@0.5.7(tailwindcss@3.4.1):
|
||||||
resolution: {integrity: sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==}
|
resolution: {integrity: sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1'
|
tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1'
|
||||||
dependencies:
|
dependencies:
|
||||||
mini-svg-data-uri: 1.4.4
|
mini-svg-data-uri: 1.4.4
|
||||||
tailwindcss: 3.4.0
|
tailwindcss: 3.4.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@testing-library/dom@9.3.3:
|
/@testing-library/dom@9.3.3:
|
||||||
@ -2289,11 +2289,11 @@ packages:
|
|||||||
/@types/react-dom@18.2.18:
|
/@types/react-dom@18.2.18:
|
||||||
resolution: {integrity: sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==}
|
resolution: {integrity: sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/react': 18.2.46
|
'@types/react': 18.2.47
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@types/react@18.2.46:
|
/@types/react@18.2.47:
|
||||||
resolution: {integrity: sha512-nNCvVBcZlvX4NU1nRRNV/mFl1nNRuTuslAJglQsq+8ldXe5Xv0Wd2f7WTE3jOxhLH2BFfiZGC6GCp+kHQbgG+w==}
|
resolution: {integrity: sha512-xquNkkOirwyCgoClNk85BjP+aqnIS+ckAJ8i37gAbDs14jfW/J23f2GItAf33oiUPQnqNMALiFeoM9Y5mbjpVQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/prop-types': 15.7.11
|
'@types/prop-types': 15.7.11
|
||||||
'@types/scheduler': 0.16.8
|
'@types/scheduler': 0.16.8
|
||||||
@ -2326,8 +2326,8 @@ packages:
|
|||||||
'@types/yargs-parser': 21.0.3
|
'@types/yargs-parser': 21.0.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@typescript-eslint/eslint-plugin@6.17.0(@typescript-eslint/parser@6.17.0)(eslint@8.56.0)(typescript@5.3.3):
|
/@typescript-eslint/eslint-plugin@6.18.0(@typescript-eslint/parser@6.18.0)(eslint@8.56.0)(typescript@5.3.3):
|
||||||
resolution: {integrity: sha512-Vih/4xLXmY7V490dGwBQJTpIZxH4ZFH6eCVmQ4RFkB+wmaCTDAx4dtgoWwMNGKLkqRY1L6rPqzEbjorRnDo4rQ==}
|
resolution: {integrity: sha512-3lqEvQUdCozi6d1mddWqd+kf8KxmGq2Plzx36BlkjuQe3rSTm/O98cLf0A4uDO+a5N1KD2SeEEl6fW97YHY+6w==}
|
||||||
engines: {node: ^16.0.0 || >=18.0.0}
|
engines: {node: ^16.0.0 || >=18.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
|
'@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
|
||||||
@ -2338,11 +2338,11 @@ packages:
|
|||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/regexpp': 4.10.0
|
'@eslint-community/regexpp': 4.10.0
|
||||||
'@typescript-eslint/parser': 6.17.0(eslint@8.56.0)(typescript@5.3.3)
|
'@typescript-eslint/parser': 6.18.0(eslint@8.56.0)(typescript@5.3.3)
|
||||||
'@typescript-eslint/scope-manager': 6.17.0
|
'@typescript-eslint/scope-manager': 6.18.0
|
||||||
'@typescript-eslint/type-utils': 6.17.0(eslint@8.56.0)(typescript@5.3.3)
|
'@typescript-eslint/type-utils': 6.18.0(eslint@8.56.0)(typescript@5.3.3)
|
||||||
'@typescript-eslint/utils': 6.17.0(eslint@8.56.0)(typescript@5.3.3)
|
'@typescript-eslint/utils': 6.18.0(eslint@8.56.0)(typescript@5.3.3)
|
||||||
'@typescript-eslint/visitor-keys': 6.17.0
|
'@typescript-eslint/visitor-keys': 6.18.0
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
eslint: 8.56.0
|
eslint: 8.56.0
|
||||||
graphemer: 1.4.0
|
graphemer: 1.4.0
|
||||||
@ -2355,8 +2355,8 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@typescript-eslint/parser@6.17.0(eslint@8.56.0)(typescript@5.3.3):
|
/@typescript-eslint/parser@6.18.0(eslint@8.56.0)(typescript@5.3.3):
|
||||||
resolution: {integrity: sha512-C4bBaX2orvhK+LlwrY8oWGmSl4WolCfYm513gEccdWZj0CwGadbIADb0FtVEcI+WzUyjyoBj2JRP8g25E6IB8A==}
|
resolution: {integrity: sha512-v6uR68SFvqhNQT41frCMCQpsP+5vySy6IdgjlzUWoo7ALCnpaWYcz/Ij2k4L8cEsL0wkvOviCMpjmtRtHNOKzA==}
|
||||||
engines: {node: ^16.0.0 || >=18.0.0}
|
engines: {node: ^16.0.0 || >=18.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^7.0.0 || ^8.0.0
|
eslint: ^7.0.0 || ^8.0.0
|
||||||
@ -2365,10 +2365,10 @@ packages:
|
|||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/scope-manager': 6.17.0
|
'@typescript-eslint/scope-manager': 6.18.0
|
||||||
'@typescript-eslint/types': 6.17.0
|
'@typescript-eslint/types': 6.18.0
|
||||||
'@typescript-eslint/typescript-estree': 6.17.0(typescript@5.3.3)
|
'@typescript-eslint/typescript-estree': 6.18.0(typescript@5.3.3)
|
||||||
'@typescript-eslint/visitor-keys': 6.17.0
|
'@typescript-eslint/visitor-keys': 6.18.0
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
eslint: 8.56.0
|
eslint: 8.56.0
|
||||||
typescript: 5.3.3
|
typescript: 5.3.3
|
||||||
@ -2376,16 +2376,16 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@typescript-eslint/scope-manager@6.17.0:
|
/@typescript-eslint/scope-manager@6.18.0:
|
||||||
resolution: {integrity: sha512-RX7a8lwgOi7am0k17NUO0+ZmMOX4PpjLtLRgLmT1d3lBYdWH4ssBUbwdmc5pdRX8rXon8v9x8vaoOSpkHfcXGA==}
|
resolution: {integrity: sha512-o/UoDT2NgOJ2VfHpfr+KBY2ErWvCySNUIX/X7O9g8Zzt/tXdpfEU43qbNk8LVuWUT2E0ptzTWXh79i74PP0twA==}
|
||||||
engines: {node: ^16.0.0 || >=18.0.0}
|
engines: {node: ^16.0.0 || >=18.0.0}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 6.17.0
|
'@typescript-eslint/types': 6.18.0
|
||||||
'@typescript-eslint/visitor-keys': 6.17.0
|
'@typescript-eslint/visitor-keys': 6.18.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@typescript-eslint/type-utils@6.17.0(eslint@8.56.0)(typescript@5.3.3):
|
/@typescript-eslint/type-utils@6.18.0(eslint@8.56.0)(typescript@5.3.3):
|
||||||
resolution: {integrity: sha512-hDXcWmnbtn4P2B37ka3nil3yi3VCQO2QEB9gBiHJmQp5wmyQWqnjA85+ZcE8c4FqnaB6lBwMrPkgd4aBYz3iNg==}
|
resolution: {integrity: sha512-ZeMtrXnGmTcHciJN1+u2CigWEEXgy1ufoxtWcHORt5kGvpjjIlK9MUhzHm4RM8iVy6dqSaZA/6PVkX6+r+ChjQ==}
|
||||||
engines: {node: ^16.0.0 || >=18.0.0}
|
engines: {node: ^16.0.0 || >=18.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^7.0.0 || ^8.0.0
|
eslint: ^7.0.0 || ^8.0.0
|
||||||
@ -2394,8 +2394,8 @@ packages:
|
|||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/typescript-estree': 6.17.0(typescript@5.3.3)
|
'@typescript-eslint/typescript-estree': 6.18.0(typescript@5.3.3)
|
||||||
'@typescript-eslint/utils': 6.17.0(eslint@8.56.0)(typescript@5.3.3)
|
'@typescript-eslint/utils': 6.18.0(eslint@8.56.0)(typescript@5.3.3)
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
eslint: 8.56.0
|
eslint: 8.56.0
|
||||||
ts-api-utils: 1.0.3(typescript@5.3.3)
|
ts-api-utils: 1.0.3(typescript@5.3.3)
|
||||||
@ -2404,13 +2404,13 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@typescript-eslint/types@6.17.0:
|
/@typescript-eslint/types@6.18.0:
|
||||||
resolution: {integrity: sha512-qRKs9tvc3a4RBcL/9PXtKSehI/q8wuU9xYJxe97WFxnzH8NWWtcW3ffNS+EWg8uPvIerhjsEZ+rHtDqOCiH57A==}
|
resolution: {integrity: sha512-/RFVIccwkwSdW/1zeMx3hADShWbgBxBnV/qSrex6607isYjj05t36P6LyONgqdUrNLl5TYU8NIKdHUYpFvExkA==}
|
||||||
engines: {node: ^16.0.0 || >=18.0.0}
|
engines: {node: ^16.0.0 || >=18.0.0}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@typescript-eslint/typescript-estree@6.17.0(typescript@5.3.3):
|
/@typescript-eslint/typescript-estree@6.18.0(typescript@5.3.3):
|
||||||
resolution: {integrity: sha512-gVQe+SLdNPfjlJn5VNGhlOhrXz4cajwFd5kAgWtZ9dCZf4XJf8xmgCTLIqec7aha3JwgLI2CK6GY1043FRxZwg==}
|
resolution: {integrity: sha512-klNvl+Ql4NsBNGB4W9TZ2Od03lm7aGvTbs0wYaFYsplVPhr+oeXjlPZCDI4U9jgJIDK38W1FKhacCFzCC+nbIg==}
|
||||||
engines: {node: ^16.0.0 || >=18.0.0}
|
engines: {node: ^16.0.0 || >=18.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '*'
|
typescript: '*'
|
||||||
@ -2418,8 +2418,8 @@ packages:
|
|||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 6.17.0
|
'@typescript-eslint/types': 6.18.0
|
||||||
'@typescript-eslint/visitor-keys': 6.17.0
|
'@typescript-eslint/visitor-keys': 6.18.0
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
globby: 11.1.0
|
globby: 11.1.0
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
@ -2431,8 +2431,8 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@typescript-eslint/utils@6.17.0(eslint@8.56.0)(typescript@5.3.3):
|
/@typescript-eslint/utils@6.18.0(eslint@8.56.0)(typescript@5.3.3):
|
||||||
resolution: {integrity: sha512-LofsSPjN/ITNkzV47hxas2JCsNCEnGhVvocfyOcLzT9c/tSZE7SfhS/iWtzP1lKNOEfLhRTZz6xqI8N2RzweSQ==}
|
resolution: {integrity: sha512-wiKKCbUeDPGaYEYQh1S580dGxJ/V9HI7K5sbGAVklyf+o5g3O+adnS4UNJajplF4e7z2q0uVBaTdT/yLb4XAVA==}
|
||||||
engines: {node: ^16.0.0 || >=18.0.0}
|
engines: {node: ^16.0.0 || >=18.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^7.0.0 || ^8.0.0
|
eslint: ^7.0.0 || ^8.0.0
|
||||||
@ -2440,9 +2440,9 @@ packages:
|
|||||||
'@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0)
|
'@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0)
|
||||||
'@types/json-schema': 7.0.15
|
'@types/json-schema': 7.0.15
|
||||||
'@types/semver': 7.5.6
|
'@types/semver': 7.5.6
|
||||||
'@typescript-eslint/scope-manager': 6.17.0
|
'@typescript-eslint/scope-manager': 6.18.0
|
||||||
'@typescript-eslint/types': 6.17.0
|
'@typescript-eslint/types': 6.18.0
|
||||||
'@typescript-eslint/typescript-estree': 6.17.0(typescript@5.3.3)
|
'@typescript-eslint/typescript-estree': 6.18.0(typescript@5.3.3)
|
||||||
eslint: 8.56.0
|
eslint: 8.56.0
|
||||||
semver: 7.5.4
|
semver: 7.5.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@ -2450,11 +2450,11 @@ packages:
|
|||||||
- typescript
|
- typescript
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@typescript-eslint/visitor-keys@6.17.0:
|
/@typescript-eslint/visitor-keys@6.18.0:
|
||||||
resolution: {integrity: sha512-H6VwB/k3IuIeQOyYczyyKN8wH6ed8EwliaYHLxOIhyF0dYEIsN8+Bk3GE19qafeMKyZJJHP8+O1HiFhFLUNKSg==}
|
resolution: {integrity: sha512-1wetAlSZpewRDb2h9p/Q8kRjdGuqdTAQbkJIOUMLug2LBLG+QOjiWoSj6/3B/hA9/tVTFFdtiKvAYoYnSRW/RA==}
|
||||||
engines: {node: ^16.0.0 || >=18.0.0}
|
engines: {node: ^16.0.0 || >=18.0.0}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 6.17.0
|
'@typescript-eslint/types': 6.18.0
|
||||||
eslint-visitor-keys: 3.4.3
|
eslint-visitor-keys: 3.4.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
@ -3476,11 +3476,11 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@next/eslint-plugin-next': 14.0.4
|
'@next/eslint-plugin-next': 14.0.4
|
||||||
'@rushstack/eslint-patch': 1.6.1
|
'@rushstack/eslint-patch': 1.6.1
|
||||||
'@typescript-eslint/parser': 6.17.0(eslint@8.56.0)(typescript@5.3.3)
|
'@typescript-eslint/parser': 6.18.0(eslint@8.56.0)(typescript@5.3.3)
|
||||||
eslint: 8.56.0
|
eslint: 8.56.0
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.17.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0)
|
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0)
|
||||||
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.17.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0)
|
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0)
|
||||||
eslint-plugin-jsx-a11y: 6.8.0(eslint@8.56.0)
|
eslint-plugin-jsx-a11y: 6.8.0(eslint@8.56.0)
|
||||||
eslint-plugin-react: 7.33.2(eslint@8.56.0)
|
eslint-plugin-react: 7.33.2(eslint@8.56.0)
|
||||||
eslint-plugin-react-hooks: 4.6.0(eslint@8.56.0)
|
eslint-plugin-react-hooks: 4.6.0(eslint@8.56.0)
|
||||||
@ -3500,7 +3500,7 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.17.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0):
|
/eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0):
|
||||||
resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==}
|
resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==}
|
||||||
engines: {node: ^14.18.0 || >=16.0.0}
|
engines: {node: ^14.18.0 || >=16.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -3510,8 +3510,8 @@ packages:
|
|||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
enhanced-resolve: 5.15.0
|
enhanced-resolve: 5.15.0
|
||||||
eslint: 8.56.0
|
eslint: 8.56.0
|
||||||
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.17.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0)
|
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0)
|
||||||
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.17.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0)
|
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0)
|
||||||
fast-glob: 3.3.2
|
fast-glob: 3.3.2
|
||||||
get-tsconfig: 4.7.2
|
get-tsconfig: 4.7.2
|
||||||
is-core-module: 2.13.1
|
is-core-module: 2.13.1
|
||||||
@ -3523,7 +3523,7 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/eslint-module-utils@2.8.0(@typescript-eslint/parser@6.17.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0):
|
/eslint-module-utils@2.8.0(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0):
|
||||||
resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
|
resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -3544,16 +3544,16 @@ packages:
|
|||||||
eslint-import-resolver-webpack:
|
eslint-import-resolver-webpack:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/parser': 6.17.0(eslint@8.56.0)(typescript@5.3.3)
|
'@typescript-eslint/parser': 6.18.0(eslint@8.56.0)(typescript@5.3.3)
|
||||||
debug: 3.2.7
|
debug: 3.2.7
|
||||||
eslint: 8.56.0
|
eslint: 8.56.0
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.17.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0)
|
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.17.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0):
|
/eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0):
|
||||||
resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==}
|
resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -3563,7 +3563,7 @@ packages:
|
|||||||
'@typescript-eslint/parser':
|
'@typescript-eslint/parser':
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/parser': 6.17.0(eslint@8.56.0)(typescript@5.3.3)
|
'@typescript-eslint/parser': 6.18.0(eslint@8.56.0)(typescript@5.3.3)
|
||||||
array-includes: 3.1.7
|
array-includes: 3.1.7
|
||||||
array.prototype.findlastindex: 1.2.3
|
array.prototype.findlastindex: 1.2.3
|
||||||
array.prototype.flat: 1.3.2
|
array.prototype.flat: 1.3.2
|
||||||
@ -3572,7 +3572,7 @@ packages:
|
|||||||
doctrine: 2.1.0
|
doctrine: 2.1.0
|
||||||
eslint: 8.56.0
|
eslint: 8.56.0
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.17.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0)
|
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0)
|
||||||
hasown: 2.0.0
|
hasown: 2.0.0
|
||||||
is-core-module: 2.13.1
|
is-core-module: 2.13.1
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
@ -6305,8 +6305,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
|
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/tailwindcss@3.4.0:
|
/tailwindcss@3.4.1:
|
||||||
resolution: {integrity: sha512-VigzymniH77knD1dryXbyxR+ePHihHociZbXnLZHUyzf2MMs2ZVqlUrZ3FvpXP8pno9JzmILt1sZPD19M3IxtA==}
|
resolution: {integrity: sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@ -1,18 +0,0 @@
|
|||||||
import FooterAuth from '@/site/FooterAuth';
|
|
||||||
import PageContentContainer from '@/components/PageContentContainer';
|
|
||||||
import { SessionProvider } from 'next-auth/react';
|
|
||||||
|
|
||||||
export default function RootLayout({
|
|
||||||
children,
|
|
||||||
}: {
|
|
||||||
children: React.ReactNode
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<SessionProvider>
|
|
||||||
<PageContentContainer>
|
|
||||||
{children}
|
|
||||||
</PageContentContainer>
|
|
||||||
<FooterAuth />
|
|
||||||
</SessionProvider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
import FooterStatic from '@/site/FooterStatic';
|
|
||||||
import PageContentContainer from '@/components/PageContentContainer';
|
|
||||||
|
|
||||||
export default function RootLayout({
|
|
||||||
children,
|
|
||||||
}: {
|
|
||||||
children: React.ReactNode
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<PageContentContainer>
|
|
||||||
{children}
|
|
||||||
</PageContentContainer>
|
|
||||||
<FooterStatic />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -9,6 +9,10 @@ import ThemeProviderClient from '@/site/ThemeProviderClient';
|
|||||||
import Nav from '@/site/Nav';
|
import Nav from '@/site/Nav';
|
||||||
import ToasterWithThemes from '@/toast/ToasterWithThemes';
|
import ToasterWithThemes from '@/toast/ToasterWithThemes';
|
||||||
import PhotoEscapeHandler from '@/photo/PhotoEscapeHandler';
|
import PhotoEscapeHandler from '@/photo/PhotoEscapeHandler';
|
||||||
|
import Footer from '@/site/Footer';
|
||||||
|
import { Suspense } from 'react';
|
||||||
|
import FooterClient from '@/site/FooterClient';
|
||||||
|
import NavClient from '@/site/NavClient';
|
||||||
|
|
||||||
import '../site/globals.css';
|
import '../site/globals.css';
|
||||||
|
|
||||||
@ -68,21 +72,31 @@ export default function RootLayout({
|
|||||||
suppressHydrationWarning
|
suppressHydrationWarning
|
||||||
>
|
>
|
||||||
<body className={ibmPlexMono.variable}>
|
<body className={ibmPlexMono.variable}>
|
||||||
<ThemeProviderClient>
|
<StateProvider>
|
||||||
<main className={clsx(
|
<ThemeProviderClient>
|
||||||
'px-3 pb-3',
|
<main className={clsx(
|
||||||
'lg:px-6 lg:pb-6',
|
'mx-3 mb-3',
|
||||||
)}>
|
'lg:mx-6 lg:mb-6',
|
||||||
<Nav />
|
)}>
|
||||||
<StateProvider>
|
<Suspense fallback={<NavClient />}>
|
||||||
{children}
|
<Nav />
|
||||||
</StateProvider>
|
</Suspense>
|
||||||
<Analytics />
|
<div className={clsx(
|
||||||
<SpeedInsights />
|
'min-h-[16rem] sm:min-h-[30rem]',
|
||||||
</main>
|
'mb-12',
|
||||||
<PhotoEscapeHandler />
|
)}>
|
||||||
<ToasterWithThemes />
|
{children}
|
||||||
</ThemeProviderClient>
|
</div>
|
||||||
|
<Suspense fallback={<FooterClient />}>
|
||||||
|
<Footer />
|
||||||
|
</Suspense>
|
||||||
|
</main>
|
||||||
|
</ThemeProviderClient>
|
||||||
|
</StateProvider>
|
||||||
|
<Analytics />
|
||||||
|
<SpeedInsights />
|
||||||
|
<PhotoEscapeHandler />
|
||||||
|
<ToasterWithThemes />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -9,7 +9,7 @@ export const signInAction = async (
|
|||||||
try {
|
try {
|
||||||
await signIn('credentials', Object.fromEntries(formData));
|
await signIn('credentials', Object.fromEntries(formData));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if ((error as Error).message.includes(CREDENTIALS_SIGN_IN_ERROR)) {
|
if ((`${error}`).includes(CREDENTIALS_SIGN_IN_ERROR)) {
|
||||||
return CREDENTIALS_SIGN_IN_ERROR;
|
return CREDENTIALS_SIGN_IN_ERROR;
|
||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
4
src/cache/index.ts
vendored
4
src/cache/index.ts
vendored
@ -28,6 +28,8 @@ import { getBlobPhotoUrls, getBlobUploadUrls } from '@/services/blob';
|
|||||||
import type { Session } from 'next-auth';
|
import type { Session } from 'next-auth';
|
||||||
import { createCameraKey } from '@/camera';
|
import { createCameraKey } from '@/camera';
|
||||||
import { PATHS_ADMIN } from '@/site/paths';
|
import { PATHS_ADMIN } from '@/site/paths';
|
||||||
|
import { cache } from 'react';
|
||||||
|
import { auth } from '@/auth';
|
||||||
|
|
||||||
// Table key
|
// Table key
|
||||||
const KEY_PHOTOS = 'photos';
|
const KEY_PHOTOS = 'photos';
|
||||||
@ -207,6 +209,8 @@ export const getUniqueFilmSimulationsCached =
|
|||||||
[KEY_PHOTOS, KEY_FILM_SIMULATIONS],
|
[KEY_PHOTOS, KEY_FILM_SIMULATIONS],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const authCached = cache(auth);
|
||||||
|
|
||||||
// No Store
|
// No Store
|
||||||
|
|
||||||
export const getPhotoNoStore = (...args: Parameters<typeof getPhoto>) => {
|
export const getPhotoNoStore = (...args: Parameters<typeof getPhoto>) => {
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
export default function PageContentContainer({
|
|
||||||
children,
|
|
||||||
}: {
|
|
||||||
children: React.ReactNode
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div className="min-h-[16rem] sm:min-h-[30rem]">
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -12,12 +12,15 @@ export default function RepoLink() {
|
|||||||
href="http://github.com/sambecker/exif-photo-blog"
|
href="http://github.com/sambecker/exif-photo-blog"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'flex items-center gap-1',
|
'flex items-center gap-0.5',
|
||||||
'text-black dark:text-white',
|
'text-main hover:text-main',
|
||||||
'hover:underline',
|
'hover:underline',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<BiLogoGithub className="translate-y-[1px] hidden xs:inline-block" />
|
<BiLogoGithub
|
||||||
|
size={16}
|
||||||
|
className="translate-y-[0.5px] hidden xs:inline-block"
|
||||||
|
/>
|
||||||
exif-photo-blog
|
exif-photo-blog
|
||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
9
src/site/Footer.tsx
Normal file
9
src/site/Footer.tsx
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { authCached } from '@/cache';
|
||||||
|
import FooterClient from './FooterClient';
|
||||||
|
|
||||||
|
export default async function Footer() {
|
||||||
|
const session = await authCached();
|
||||||
|
return (
|
||||||
|
<FooterClient userEmail={session?.user?.email} />
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,60 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import { clsx } from 'clsx/lite';
|
|
||||||
import Link from 'next/link';
|
|
||||||
import { useSession } from 'next-auth/react';
|
|
||||||
import ThemeSwitcher from '@/site/ThemeSwitcher';
|
|
||||||
import SiteGrid from '../components/SiteGrid';
|
|
||||||
import { usePathname } from 'next/navigation';
|
|
||||||
import { isPathSignIn } from '@/site/paths';
|
|
||||||
import { signOutAction } from '@/auth/action';
|
|
||||||
import SubmitButtonWithStatus from '@/components/SubmitButtonWithStatus';
|
|
||||||
|
|
||||||
const LINK_STYLE = clsx(
|
|
||||||
'cursor-pointer',
|
|
||||||
'hover:text-gray-300',
|
|
||||||
'hover:dark:text-gray-600',
|
|
||||||
);
|
|
||||||
|
|
||||||
export default function FooterAuth() {
|
|
||||||
const { data: session, status } = useSession();
|
|
||||||
|
|
||||||
const path = usePathname();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SiteGrid
|
|
||||||
contentMain={<div className={clsx(
|
|
||||||
'flex items-center',
|
|
||||||
'my-8',
|
|
||||||
'text-dim',
|
|
||||||
)}>
|
|
||||||
<div className="flex gap-x-4 gap-y-1 flex-wrap items-center flex-grow">
|
|
||||||
{status === 'loading'
|
|
||||||
? <>Loading ...</>
|
|
||||||
: <>
|
|
||||||
{session?.user?.email && <div>
|
|
||||||
{session.user.email}
|
|
||||||
</div>}
|
|
||||||
{status === 'authenticated' &&
|
|
||||||
<form action={signOutAction}>
|
|
||||||
<SubmitButtonWithStatus
|
|
||||||
className={LINK_STYLE}
|
|
||||||
styleAsLink
|
|
||||||
>
|
|
||||||
Sign Out
|
|
||||||
</SubmitButtonWithStatus>
|
|
||||||
</form>}
|
|
||||||
{status === 'unauthenticated' &&
|
|
||||||
<Link
|
|
||||||
href="/sign-in"
|
|
||||||
className={LINK_STYLE}
|
|
||||||
>
|
|
||||||
Sign In
|
|
||||||
</Link>}
|
|
||||||
</>}
|
|
||||||
</div>
|
|
||||||
{!isPathSignIn(path) && <ThemeSwitcher />}
|
|
||||||
</div>}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
70
src/site/FooterClient.tsx
Normal file
70
src/site/FooterClient.tsx
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { clsx } from 'clsx/lite';
|
||||||
|
import SiteGrid from '../components/SiteGrid';
|
||||||
|
import ThemeSwitcher from '@/site/ThemeSwitcher';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { SHOW_REPO_LINK } from '@/site/config';
|
||||||
|
import RepoLink from '../components/RepoLink';
|
||||||
|
import { usePathname } from 'next/navigation';
|
||||||
|
import { isPathAdmin, isPathSignIn, pathForAdminPhotos } from './paths';
|
||||||
|
import SubmitButtonWithStatus from '@/components/SubmitButtonWithStatus';
|
||||||
|
import { signOutAction } from '@/auth/action';
|
||||||
|
import Spinner from '@/components/Spinner';
|
||||||
|
import AnimateItems from '@/components/AnimateItems';
|
||||||
|
|
||||||
|
export default function FooterClient({
|
||||||
|
userEmail,
|
||||||
|
}: {
|
||||||
|
userEmail?: string | null | undefined
|
||||||
|
}) {
|
||||||
|
const pathname = usePathname();
|
||||||
|
|
||||||
|
const showFooter = !isPathSignIn(pathname);
|
||||||
|
|
||||||
|
const shouldAnimate = !isPathAdmin(pathname);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SiteGrid
|
||||||
|
contentMain={
|
||||||
|
<AnimateItems
|
||||||
|
type={!shouldAnimate ? 'none' : 'bottom'}
|
||||||
|
distanceOffset={10}
|
||||||
|
items={showFooter
|
||||||
|
? [<div
|
||||||
|
key="footer"
|
||||||
|
className={clsx(
|
||||||
|
'flex items-center',
|
||||||
|
'text-dim min-h-[4rem]',
|
||||||
|
)}>
|
||||||
|
<div className="flex gap-x-4 gap-y-1 flex-grow flex-wrap h-4">
|
||||||
|
{isPathAdmin(pathname)
|
||||||
|
? <>
|
||||||
|
{userEmail === undefined &&
|
||||||
|
<Spinner />}
|
||||||
|
{userEmail && <>
|
||||||
|
<div>{userEmail}</div>
|
||||||
|
<form action={signOutAction}>
|
||||||
|
<SubmitButtonWithStatus styleAsLink>
|
||||||
|
Sign out
|
||||||
|
</SubmitButtonWithStatus>
|
||||||
|
</form>
|
||||||
|
</>}
|
||||||
|
</>
|
||||||
|
: <>
|
||||||
|
<Link href={pathForAdminPhotos()}>
|
||||||
|
Admin
|
||||||
|
</Link>
|
||||||
|
{SHOW_REPO_LINK &&
|
||||||
|
<RepoLink />}
|
||||||
|
</>}
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center h-4">
|
||||||
|
<ThemeSwitcher />
|
||||||
|
</div>
|
||||||
|
</div>]
|
||||||
|
: []}
|
||||||
|
/>}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,47 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import { clsx } from 'clsx/lite';
|
|
||||||
import SiteGrid from '../components/SiteGrid';
|
|
||||||
import ThemeSwitcher from '@/site/ThemeSwitcher';
|
|
||||||
import { signOut } from 'next-auth/react';
|
|
||||||
import Link from 'next/link';
|
|
||||||
import { SHOW_REPO_LINK } from '@/site/config';
|
|
||||||
import RepoLink from '../components/RepoLink';
|
|
||||||
|
|
||||||
export default function FooterStatic({
|
|
||||||
showSignOut,
|
|
||||||
}: {
|
|
||||||
showSignOut?: boolean
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<SiteGrid
|
|
||||||
contentMain={<div className={clsx(
|
|
||||||
'my-8',
|
|
||||||
'flex items-center',
|
|
||||||
'text-dim',
|
|
||||||
)}>
|
|
||||||
<div className="flex gap-x-4 gap-y-1 flex-grow flex-wrap">
|
|
||||||
<Link
|
|
||||||
href="/admin/photos"
|
|
||||||
className="hover:text-gray-600 dark:hover:text-gray-400"
|
|
||||||
>
|
|
||||||
Admin
|
|
||||||
</Link>
|
|
||||||
{SHOW_REPO_LINK &&
|
|
||||||
<RepoLink />}
|
|
||||||
{showSignOut &&
|
|
||||||
<div
|
|
||||||
className={clsx(
|
|
||||||
'cursor-pointer',
|
|
||||||
'hover:text-gray-600 dark:hover:text-gray-400',
|
|
||||||
)}
|
|
||||||
onClick={() => signOut()}
|
|
||||||
>
|
|
||||||
Sign out
|
|
||||||
</div>}
|
|
||||||
</div>
|
|
||||||
<ThemeSwitcher />
|
|
||||||
</div>}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,82 +1,9 @@
|
|||||||
'use client';
|
import { authCached } from '@/cache';
|
||||||
|
import NavClient from './NavClient';
|
||||||
import { clsx } from 'clsx/lite';
|
|
||||||
import { usePathname } from 'next/navigation';
|
|
||||||
import Link from 'next/link';
|
|
||||||
import SiteGrid from '../components/SiteGrid';
|
|
||||||
import { SITE_DOMAIN_OR_TITLE } from '@/site/config';
|
|
||||||
import ViewSwitcher, { SwitcherSelection } from '@/site/ViewSwitcher';
|
|
||||||
import {
|
|
||||||
PATH_ADMIN,
|
|
||||||
PATH_ROOT,
|
|
||||||
isPathAdmin,
|
|
||||||
isPathGrid,
|
|
||||||
isPathProtected,
|
|
||||||
isPathSets,
|
|
||||||
isPathSignIn,
|
|
||||||
} from '@/site/paths';
|
|
||||||
import AnimateItems from '../components/AnimateItems';
|
|
||||||
|
|
||||||
export default function Nav({ showTextLinks }: { showTextLinks?: boolean }) {
|
|
||||||
const isLoggedIn = false;
|
|
||||||
|
|
||||||
const pathname = usePathname();
|
|
||||||
|
|
||||||
const showNav = !isPathSignIn(pathname);
|
|
||||||
|
|
||||||
const shouldAnimate = !isPathAdmin(pathname);
|
|
||||||
|
|
||||||
const renderLink = (
|
|
||||||
text: string,
|
|
||||||
linkOrAction: string | (() => void),
|
|
||||||
) =>
|
|
||||||
typeof linkOrAction === 'string'
|
|
||||||
? <Link href={linkOrAction}>{text}</Link>
|
|
||||||
: <button onClick={linkOrAction}>{text}</button>;
|
|
||||||
|
|
||||||
const switcherSelectionForPath = (): SwitcherSelection | undefined => {
|
|
||||||
if (pathname === PATH_ROOT) {
|
|
||||||
return 'full-frame';
|
|
||||||
} else if (isPathGrid(pathname)) {
|
|
||||||
return 'grid';
|
|
||||||
} else if (isPathSets(pathname)) {
|
|
||||||
return 'sets';
|
|
||||||
} else if (isPathProtected(pathname)) {
|
|
||||||
return 'admin';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
export default async function Nav() {
|
||||||
|
const session = await authCached();
|
||||||
return (
|
return (
|
||||||
<SiteGrid
|
<NavClient showAdmin={Boolean(session?.user?.email)} />
|
||||||
contentMain={
|
|
||||||
<AnimateItems
|
|
||||||
type={!shouldAnimate ? 'none' : 'bottom'}
|
|
||||||
distanceOffset={10}
|
|
||||||
items={showNav
|
|
||||||
? [<div
|
|
||||||
key="nav"
|
|
||||||
className={clsx(
|
|
||||||
'flex items-center',
|
|
||||||
'w-full min-h-[4rem]',
|
|
||||||
'leading-none',
|
|
||||||
)}>
|
|
||||||
<div className="flex flex-grow items-center gap-4">
|
|
||||||
<ViewSwitcher
|
|
||||||
currentSelection={switcherSelectionForPath()}
|
|
||||||
showAdmin={isLoggedIn}
|
|
||||||
/>
|
|
||||||
{showTextLinks && <>
|
|
||||||
{renderLink('Home', PATH_ROOT)}
|
|
||||||
{renderLink('Admin', PATH_ADMIN)}
|
|
||||||
</>}
|
|
||||||
</div>
|
|
||||||
<div className="hidden xs:block">
|
|
||||||
{renderLink(SITE_DOMAIN_OR_TITLE, PATH_ROOT)}
|
|
||||||
</div>
|
|
||||||
</div>]
|
|
||||||
: []}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|||||||
79
src/site/NavClient.tsx
Normal file
79
src/site/NavClient.tsx
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { clsx } from 'clsx/lite';
|
||||||
|
import { usePathname } from 'next/navigation';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import SiteGrid from '../components/SiteGrid';
|
||||||
|
import { SITE_DOMAIN_OR_TITLE } from '@/site/config';
|
||||||
|
import ViewSwitcher, { SwitcherSelection } from '@/site/ViewSwitcher';
|
||||||
|
import {
|
||||||
|
PATH_ROOT,
|
||||||
|
isPathAdmin,
|
||||||
|
isPathGrid,
|
||||||
|
isPathProtected,
|
||||||
|
isPathSets,
|
||||||
|
isPathSignIn,
|
||||||
|
} from '@/site/paths';
|
||||||
|
import AnimateItems from '../components/AnimateItems';
|
||||||
|
|
||||||
|
export default function NavClient({
|
||||||
|
showAdmin,
|
||||||
|
}: {
|
||||||
|
showAdmin?: boolean,
|
||||||
|
}) {
|
||||||
|
const pathname = usePathname();
|
||||||
|
|
||||||
|
const showNav = !isPathSignIn(pathname);
|
||||||
|
|
||||||
|
const shouldAnimate = !isPathAdmin(pathname);
|
||||||
|
|
||||||
|
const renderLink = (
|
||||||
|
text: string,
|
||||||
|
linkOrAction: string | (() => void),
|
||||||
|
) =>
|
||||||
|
typeof linkOrAction === 'string'
|
||||||
|
? <Link href={linkOrAction}>{text}</Link>
|
||||||
|
: <button onClick={linkOrAction}>{text}</button>;
|
||||||
|
|
||||||
|
const switcherSelectionForPath = (): SwitcherSelection | undefined => {
|
||||||
|
if (pathname === PATH_ROOT) {
|
||||||
|
return 'full-frame';
|
||||||
|
} else if (isPathGrid(pathname)) {
|
||||||
|
return 'grid';
|
||||||
|
} else if (isPathSets(pathname)) {
|
||||||
|
return 'sets';
|
||||||
|
} else if (isPathProtected(pathname)) {
|
||||||
|
return 'admin';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SiteGrid
|
||||||
|
contentMain={
|
||||||
|
<AnimateItems
|
||||||
|
type={!shouldAnimate ? 'none' : 'bottom'}
|
||||||
|
distanceOffset={10}
|
||||||
|
items={showNav
|
||||||
|
? [<div
|
||||||
|
key="nav"
|
||||||
|
className={clsx(
|
||||||
|
'flex items-center',
|
||||||
|
'w-full min-h-[4rem]',
|
||||||
|
'leading-none',
|
||||||
|
)}>
|
||||||
|
<div className="flex flex-grow items-center gap-4">
|
||||||
|
<ViewSwitcher
|
||||||
|
currentSelection={switcherSelectionForPath()}
|
||||||
|
showAdmin={showAdmin}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="hidden xs:block">
|
||||||
|
{renderLink(SITE_DOMAIN_OR_TITLE, PATH_ROOT)}
|
||||||
|
</div>
|
||||||
|
</div>]
|
||||||
|
: []}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -2,7 +2,7 @@ import Switcher from '@/components/Switcher';
|
|||||||
import SwitcherItem from '@/components/SwitcherItem';
|
import SwitcherItem from '@/components/SwitcherItem';
|
||||||
import IconFullFrame from '@/site/IconFullFrame';
|
import IconFullFrame from '@/site/IconFullFrame';
|
||||||
import IconGrid from '@/site/IconGrid';
|
import IconGrid from '@/site/IconGrid';
|
||||||
import { PATH_GRID, PATH_SETS } from '@/site/paths';
|
import { PATH_ADMIN_PHOTOS, PATH_GRID, PATH_SETS } from '@/site/paths';
|
||||||
import { BiLockAlt } from 'react-icons/bi';
|
import { BiLockAlt } from 'react-icons/bi';
|
||||||
import IconSets from './IconSets';
|
import IconSets from './IconSets';
|
||||||
|
|
||||||
@ -38,8 +38,8 @@ export default function ViewSwitcher({
|
|||||||
/>
|
/>
|
||||||
{showAdmin &&
|
{showAdmin &&
|
||||||
<SwitcherItem
|
<SwitcherItem
|
||||||
icon={<BiLockAlt size={15} className="-translate-y-[1px]" />}
|
icon={<BiLockAlt size={16} className="translate-y-[-0.5px]" />}
|
||||||
href="/admin/photos"
|
href={PATH_ADMIN_PHOTOS}
|
||||||
active={currentSelection === 'admin'}
|
active={currentSelection === 'admin'}
|
||||||
/>}
|
/>}
|
||||||
</Switcher>
|
</Switcher>
|
||||||
|
|||||||
@ -107,6 +107,11 @@
|
|||||||
p-0 min-h-0
|
p-0 min-h-0
|
||||||
border-none active:bg-transparent shadow-none
|
border-none active:bg-transparent shadow-none
|
||||||
}
|
}
|
||||||
|
a, .link {
|
||||||
|
@apply
|
||||||
|
hover:text-gray-600
|
||||||
|
hover:dark:text-gray-400
|
||||||
|
}
|
||||||
/* Common Utilities */
|
/* Common Utilities */
|
||||||
.text-main {
|
.text-main {
|
||||||
@apply
|
@apply
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user