Compare commits
No commits in common. "885d17a15ca11d30ea5700fb42d6a0cc97cfda7e" and "e98c079ba674147a0d8d6d955bce7478936bd829" have entirely different histories.
885d17a15c
...
e98c079ba6
@ -23,10 +23,8 @@
|
|||||||
"@radix-ui/react-toast": "^1.2.11",
|
"@radix-ui/react-toast": "^1.2.11",
|
||||||
"@reduxjs/toolkit": "^2.7.0",
|
"@reduxjs/toolkit": "^2.7.0",
|
||||||
"aos": "^2.3.4",
|
"aos": "^2.3.4",
|
||||||
"axios": "^1.9.0",
|
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"cookies-next": "^5.1.0",
|
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"embla-carousel-autoplay": "^8.6.0",
|
"embla-carousel-autoplay": "^8.6.0",
|
||||||
"embla-carousel-react": "^8.6.0",
|
"embla-carousel-react": "^8.6.0",
|
||||||
|
|||||||
95
pnpm-lock.yaml
generated
95
pnpm-lock.yaml
generated
@ -47,18 +47,12 @@ importers:
|
|||||||
aos:
|
aos:
|
||||||
specifier: ^2.3.4
|
specifier: ^2.3.4
|
||||||
version: 2.3.4
|
version: 2.3.4
|
||||||
axios:
|
|
||||||
specifier: ^1.9.0
|
|
||||||
version: 1.9.0
|
|
||||||
class-variance-authority:
|
class-variance-authority:
|
||||||
specifier: ^0.7.1
|
specifier: ^0.7.1
|
||||||
version: 0.7.1
|
version: 0.7.1
|
||||||
clsx:
|
clsx:
|
||||||
specifier: ^2.1.1
|
specifier: ^2.1.1
|
||||||
version: 2.1.1
|
version: 2.1.1
|
||||||
cookies-next:
|
|
||||||
specifier: ^5.1.0
|
|
||||||
version: 5.1.0(next@15.3.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)
|
|
||||||
date-fns:
|
date-fns:
|
||||||
specifier: ^4.1.0
|
specifier: ^4.1.0
|
||||||
version: 4.1.0
|
version: 4.1.0
|
||||||
@ -1312,9 +1306,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
|
resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
asynckit@0.4.0:
|
|
||||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
|
||||||
|
|
||||||
available-typed-arrays@1.0.7:
|
available-typed-arrays@1.0.7:
|
||||||
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
|
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@ -1323,9 +1314,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==}
|
resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
axios@1.9.0:
|
|
||||||
resolution: {integrity: sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==}
|
|
||||||
|
|
||||||
axobject-query@4.1.0:
|
axobject-query@4.1.0:
|
||||||
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
|
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@ -1397,23 +1385,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
|
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
|
||||||
engines: {node: '>=12.5.0'}
|
engines: {node: '>=12.5.0'}
|
||||||
|
|
||||||
combined-stream@1.0.8:
|
|
||||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
|
||||||
engines: {node: '>= 0.8'}
|
|
||||||
|
|
||||||
concat-map@0.0.1:
|
concat-map@0.0.1:
|
||||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||||
|
|
||||||
cookie@1.0.2:
|
|
||||||
resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
|
|
||||||
cookies-next@5.1.0:
|
|
||||||
resolution: {integrity: sha512-9Ekne+q8hfziJtnT9c1yDUBqT0eDMGgPrfPl4bpR3xwQHLTd/8gbSf6+IEkP/pjGsDZt1TGbC6emYmFYRbIXwQ==}
|
|
||||||
peerDependencies:
|
|
||||||
next: '>=15.0.0'
|
|
||||||
react: '>= 16.8.0'
|
|
||||||
|
|
||||||
cross-spawn@7.0.6:
|
cross-spawn@7.0.6:
|
||||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@ -1467,10 +1441,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
|
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
delayed-stream@1.0.0:
|
|
||||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
|
||||||
engines: {node: '>=0.4.0'}
|
|
||||||
|
|
||||||
detect-libc@2.0.3:
|
detect-libc@2.0.3:
|
||||||
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
|
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -1741,23 +1711,10 @@ packages:
|
|||||||
flatted@3.3.3:
|
flatted@3.3.3:
|
||||||
resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
|
resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
|
||||||
|
|
||||||
follow-redirects@1.15.9:
|
|
||||||
resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
|
|
||||||
engines: {node: '>=4.0'}
|
|
||||||
peerDependencies:
|
|
||||||
debug: '*'
|
|
||||||
peerDependenciesMeta:
|
|
||||||
debug:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
for-each@0.3.5:
|
for-each@0.3.5:
|
||||||
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
|
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
form-data@4.0.2:
|
|
||||||
resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==}
|
|
||||||
engines: {node: '>= 6'}
|
|
||||||
|
|
||||||
function-bind@1.1.2:
|
function-bind@1.1.2:
|
||||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||||
|
|
||||||
@ -2133,14 +2090,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
|
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
|
||||||
engines: {node: '>=8.6'}
|
engines: {node: '>=8.6'}
|
||||||
|
|
||||||
mime-db@1.52.0:
|
|
||||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
|
||||||
engines: {node: '>= 0.6'}
|
|
||||||
|
|
||||||
mime-types@2.1.35:
|
|
||||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
|
||||||
engines: {node: '>= 0.6'}
|
|
||||||
|
|
||||||
minimatch@10.0.1:
|
minimatch@10.0.1:
|
||||||
resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
|
resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
|
||||||
engines: {node: 20 || >=22}
|
engines: {node: 20 || >=22}
|
||||||
@ -2358,9 +2307,6 @@ packages:
|
|||||||
prop-types@15.8.1:
|
prop-types@15.8.1:
|
||||||
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
||||||
|
|
||||||
proxy-from-env@1.1.0:
|
|
||||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
|
||||||
|
|
||||||
punycode@2.3.1:
|
punycode@2.3.1:
|
||||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -3846,22 +3792,12 @@ snapshots:
|
|||||||
|
|
||||||
async-function@1.0.0: {}
|
async-function@1.0.0: {}
|
||||||
|
|
||||||
asynckit@0.4.0: {}
|
|
||||||
|
|
||||||
available-typed-arrays@1.0.7:
|
available-typed-arrays@1.0.7:
|
||||||
dependencies:
|
dependencies:
|
||||||
possible-typed-array-names: 1.1.0
|
possible-typed-array-names: 1.1.0
|
||||||
|
|
||||||
axe-core@4.10.3: {}
|
axe-core@4.10.3: {}
|
||||||
|
|
||||||
axios@1.9.0:
|
|
||||||
dependencies:
|
|
||||||
follow-redirects: 1.15.9
|
|
||||||
form-data: 4.0.2
|
|
||||||
proxy-from-env: 1.1.0
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- debug
|
|
||||||
|
|
||||||
axobject-query@4.1.0: {}
|
axobject-query@4.1.0: {}
|
||||||
|
|
||||||
balanced-match@1.0.2: {}
|
balanced-match@1.0.2: {}
|
||||||
@ -3937,20 +3873,8 @@ snapshots:
|
|||||||
color-string: 1.9.1
|
color-string: 1.9.1
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
combined-stream@1.0.8:
|
|
||||||
dependencies:
|
|
||||||
delayed-stream: 1.0.0
|
|
||||||
|
|
||||||
concat-map@0.0.1: {}
|
concat-map@0.0.1: {}
|
||||||
|
|
||||||
cookie@1.0.2: {}
|
|
||||||
|
|
||||||
cookies-next@5.1.0(next@15.3.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0):
|
|
||||||
dependencies:
|
|
||||||
cookie: 1.0.2
|
|
||||||
next: 15.3.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
|
||||||
react: 19.1.0
|
|
||||||
|
|
||||||
cross-spawn@7.0.6:
|
cross-spawn@7.0.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
path-key: 3.1.1
|
path-key: 3.1.1
|
||||||
@ -4003,8 +3927,6 @@ snapshots:
|
|||||||
has-property-descriptors: 1.0.2
|
has-property-descriptors: 1.0.2
|
||||||
object-keys: 1.1.1
|
object-keys: 1.1.1
|
||||||
|
|
||||||
delayed-stream@1.0.0: {}
|
|
||||||
|
|
||||||
detect-libc@2.0.3: {}
|
detect-libc@2.0.3: {}
|
||||||
|
|
||||||
detect-node-es@1.1.0: {}
|
detect-node-es@1.1.0: {}
|
||||||
@ -4430,19 +4352,10 @@ snapshots:
|
|||||||
|
|
||||||
flatted@3.3.3: {}
|
flatted@3.3.3: {}
|
||||||
|
|
||||||
follow-redirects@1.15.9: {}
|
|
||||||
|
|
||||||
for-each@0.3.5:
|
for-each@0.3.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-callable: 1.2.7
|
is-callable: 1.2.7
|
||||||
|
|
||||||
form-data@4.0.2:
|
|
||||||
dependencies:
|
|
||||||
asynckit: 0.4.0
|
|
||||||
combined-stream: 1.0.8
|
|
||||||
es-set-tostringtag: 2.1.0
|
|
||||||
mime-types: 2.1.35
|
|
||||||
|
|
||||||
function-bind@1.1.2: {}
|
function-bind@1.1.2: {}
|
||||||
|
|
||||||
function.prototype.name@1.1.8:
|
function.prototype.name@1.1.8:
|
||||||
@ -4795,12 +4708,6 @@ snapshots:
|
|||||||
braces: 3.0.3
|
braces: 3.0.3
|
||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
|
|
||||||
mime-db@1.52.0: {}
|
|
||||||
|
|
||||||
mime-types@2.1.35:
|
|
||||||
dependencies:
|
|
||||||
mime-db: 1.52.0
|
|
||||||
|
|
||||||
minimatch@10.0.1:
|
minimatch@10.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion: 2.0.1
|
brace-expansion: 2.0.1
|
||||||
@ -4970,8 +4877,6 @@ snapshots:
|
|||||||
object-assign: 4.1.1
|
object-assign: 4.1.1
|
||||||
react-is: 16.13.1
|
react-is: 16.13.1
|
||||||
|
|
||||||
proxy-from-env@1.1.0: {}
|
|
||||||
|
|
||||||
punycode@2.3.1: {}
|
punycode@2.3.1: {}
|
||||||
|
|
||||||
queue-microtask@1.2.3: {}
|
queue-microtask@1.2.3: {}
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
import { Axios } from 'axios';
|
|
||||||
|
|
||||||
const oriyoClient = new Axios({
|
|
||||||
baseURL: process.env.ORIOYO_API_ENDPOINT || '',
|
|
||||||
headers: {
|
|
||||||
'Content-type': 'application/json',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default oriyoClient;
|
|
||||||
@ -1,44 +1,55 @@
|
|||||||
import { NextRequest, NextResponse } from 'next/server';
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
import oriyoClient from '@/app/api-utlities/utilities/oriyo.client';
|
import { LoginData } from '@/entities/auth/model/types';
|
||||||
|
|
||||||
import { loginFormSchema } from '@/entities/auth/model/validation/login-form.schema';
|
export const GET = async (req: NextRequest) => {
|
||||||
|
if (req.method !== 'GET') {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Method is not supported' },
|
||||||
|
{ status: 405 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
import { validationErrorHandler } from '../../middlewares/error-handler.middleware';
|
const { searchParams } = req.nextUrl;
|
||||||
|
|
||||||
const routeHandler = async (req: NextRequest) => {
|
const phoneNumber = searchParams.get('phoneNumber');
|
||||||
const body = await req.json();
|
const cardNumber = searchParams.get('cardNumber');
|
||||||
|
const type = searchParams.get('type');
|
||||||
|
|
||||||
const validatedBody = loginFormSchema
|
if (!phoneNumber || !cardNumber || !type) {
|
||||||
.merge(z.object({ type: z.enum(['bonus', 'corporate']) }))
|
return NextResponse.json({ error: 'Bad request' }, { status: 400 });
|
||||||
.parse(body);
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const oriyoResponse = await oriyoClient.get('/client/login', {
|
const loginRes = await fetch(
|
||||||
params: {
|
`https://test.oriyo.tj/api/client/login?type=${type}&phone=${phoneNumber}&uid=${cardNumber}`,
|
||||||
type: validatedBody.type,
|
{
|
||||||
phone: validatedBody.phoneNumber,
|
method: 'GET',
|
||||||
uid: validatedBody.cardNumber,
|
|
||||||
},
|
},
|
||||||
});
|
);
|
||||||
|
|
||||||
const { token, card_id } = JSON.parse(oriyoResponse.data);
|
if (!loginRes.ok) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Error during login' },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = (await loginRes.json()) as LoginData;
|
||||||
|
|
||||||
|
const token = data.token;
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return NextResponse.json({ error: 'Credentials error' }, { status: 401 });
|
return NextResponse.json({ error: 'No auth token' }, { status: 401 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = NextResponse.json({ success: true });
|
const response = NextResponse.json({ success: true });
|
||||||
|
|
||||||
response.cookies.set(
|
response.cookies.set('token', token, {
|
||||||
`${validatedBody.type}__token`,
|
httpOnly: true,
|
||||||
JSON.stringify({ token, card_id }),
|
|
||||||
{
|
|
||||||
path: '/',
|
path: '/',
|
||||||
maxAge: 2 * 60 * 60,
|
maxAge: 2 * 60 * 60,
|
||||||
},
|
secure: process.env.NODE_ENV === 'production',
|
||||||
);
|
});
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -46,5 +57,3 @@ const routeHandler = async (req: NextRequest) => {
|
|||||||
return NextResponse.json({ error: 'Server error' }, { status: 500 });
|
return NextResponse.json({ error: 'Server error' }, { status: 500 });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const POST = validationErrorHandler(routeHandler);
|
|
||||||
|
|||||||
@ -1,31 +0,0 @@
|
|||||||
import { NextRequest, NextResponse } from 'next/server';
|
|
||||||
|
|
||||||
import oriyoClient from '@/app/api-utlities/utilities/oriyo.client';
|
|
||||||
|
|
||||||
import { validationErrorHandler } from '../../middlewares/error-handler.middleware';
|
|
||||||
|
|
||||||
export const routeHandler = async (req: NextRequest) => {
|
|
||||||
const bonusTokenData = req.cookies.get('bonus__token');
|
|
||||||
|
|
||||||
if (!bonusTokenData) {
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: 'User does not have access' },
|
|
||||||
{ status: 401 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { card_id, token } = JSON.parse(bonusTokenData.value);
|
|
||||||
|
|
||||||
const oriyoResponse = await oriyoClient.get('/client/info', {
|
|
||||||
params: {
|
|
||||||
card_id,
|
|
||||||
token,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return new Response(oriyoResponse.data, {
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const GET = validationErrorHandler(routeHandler);
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
import { NextRequest, NextResponse } from 'next/server';
|
|
||||||
import { ZodError } from 'zod';
|
|
||||||
|
|
||||||
export const validationErrorHandler =
|
|
||||||
(handler: Function) => async (req: NextRequest, res: NextResponse) => {
|
|
||||||
try {
|
|
||||||
return await handler(req, res);
|
|
||||||
} catch (error) {
|
|
||||||
if (error instanceof ZodError)
|
|
||||||
return NextResponse.json({ message: error.format() }, { status: 400 });
|
|
||||||
|
|
||||||
console.error(error);
|
|
||||||
return NextResponse.json(
|
|
||||||
{ message: 'Server died for some reason' },
|
|
||||||
{ status: 500 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -7,9 +7,7 @@ import {
|
|||||||
import { mainPageRequest } from '@/app/api-utlities/requests/main-page.request';
|
import { mainPageRequest } from '@/app/api-utlities/requests/main-page.request';
|
||||||
import { requestTaylor } from '@/app/api-utlities/utilities/taylor.client';
|
import { requestTaylor } from '@/app/api-utlities/utilities/taylor.client';
|
||||||
|
|
||||||
import { validationErrorHandler } from '../../middlewares/error-handler.middleware';
|
export async function GET(request: Request) {
|
||||||
|
|
||||||
const routeHandler = async (request: Request) => {
|
|
||||||
const response = await requestTaylor(mainPageRequest);
|
const response = await requestTaylor(mainPageRequest);
|
||||||
|
|
||||||
return new Response(
|
return new Response(
|
||||||
@ -23,6 +21,4 @@ const routeHandler = async (request: Request) => {
|
|||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
export const GET = validationErrorHandler(routeHandler);
|
|
||||||
|
|||||||
@ -1,23 +1,24 @@
|
|||||||
import { baseAPI } from '@/shared/api/base-api';
|
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
|
||||||
|
|
||||||
import { LoginParams, LoginResponse } from '../model/contracts/login.contract';
|
import { LoginParams, LoginResponse } from '../model/contracts/login.contract';
|
||||||
|
|
||||||
export const authenticationApi = baseAPI.injectEndpoints({
|
export const loginAPI = createApi({
|
||||||
endpoints: (builder) => ({
|
baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
|
||||||
login: builder.query<LoginResponse, LoginParams>({
|
endpoints: (build) => ({
|
||||||
|
login: build.query<LoginResponse, LoginParams>({
|
||||||
query: (data) => {
|
query: (data) => {
|
||||||
return {
|
const params = new URLSearchParams({
|
||||||
method: 'POST',
|
|
||||||
body: {
|
|
||||||
type: data.type,
|
type: data.type,
|
||||||
phoneNumber: data.phoneNumber,
|
phoneNumber: data.phoneNumber,
|
||||||
cardNumber: data.cardNumber,
|
cardNumber: data.cardNumber,
|
||||||
},
|
}).toString();
|
||||||
url: '/auth/login',
|
|
||||||
|
return {
|
||||||
|
url: `/auth/login?${params}`,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { useLazyLoginQuery } = authenticationApi;
|
export const { useLazyLoginQuery } = loginAPI;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { LoginFormData } from '@/entities/auth/model/validation/login-form.schema';
|
import { LoginFormData } from '@/features/auth/login-form/model/login-form.schema';
|
||||||
|
|
||||||
export interface LoginResponse {
|
export interface LoginResponse {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
import { baseAPI } from '@/shared/api/base-api';
|
|
||||||
|
|
||||||
import { ClientInfo } from '../model/types/bonus-client-info.type';
|
|
||||||
|
|
||||||
export const bonusApi = baseAPI.injectEndpoints({
|
|
||||||
endpoints: (builder) => ({
|
|
||||||
fetchMyBonusInfo: builder.query<ClientInfo, any>({
|
|
||||||
query: () => {
|
|
||||||
return {
|
|
||||||
url: '/bonus/info',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { useFetchMyBonusInfoQuery } = bonusApi;
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
export interface ClientInfo {
|
|
||||||
card_id: number;
|
|
||||||
fullname: string;
|
|
||||||
cardno: string;
|
|
||||||
reg_date: string;
|
|
||||||
end_date: string;
|
|
||||||
bonuses: string;
|
|
||||||
}
|
|
||||||
@ -19,10 +19,7 @@ import {
|
|||||||
} from '@/shared/shadcn-ui/form';
|
} from '@/shared/shadcn-ui/form';
|
||||||
import { Input } from '@/shared/shadcn-ui/input';
|
import { Input } from '@/shared/shadcn-ui/input';
|
||||||
|
|
||||||
import {
|
import { LoginFormData, loginFormSchema } from '../model/login-form.schema';
|
||||||
LoginFormData,
|
|
||||||
loginFormSchema,
|
|
||||||
} from '../../../../entities/auth/model/validation/login-form.schema';
|
|
||||||
|
|
||||||
interface LoginFormProps {
|
interface LoginFormProps {
|
||||||
type: 'bonus' | 'corporate';
|
type: 'bonus' | 'corporate';
|
||||||
@ -43,12 +40,16 @@ export const LoginForm = ({ type }: LoginFormProps) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const onSubmit = async (data: LoginFormData) => {
|
const onSubmit = async (data: LoginFormData) => {
|
||||||
|
try {
|
||||||
await login({ ...data, type }).unwrap();
|
await login({ ...data, type }).unwrap();
|
||||||
|
|
||||||
toast.success('Logged in successfully!');
|
toast.success('Logged in successfully!');
|
||||||
router.push(
|
router.push(
|
||||||
type === 'bonus' ? '/customer-dashboard' : '/corporate-dashboard',
|
type === 'bonus' ? '/customer-dashboard' : '/corporate-dashboard',
|
||||||
);
|
);
|
||||||
|
} catch (error) {
|
||||||
|
toast.error('An error occured during login');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
import { ArrowUpRight, Clock, CreditCard, LogOut, User } from 'lucide-react';
|
import { ArrowUpRight, Clock, CreditCard, LogOut, User } from 'lucide-react';
|
||||||
|
|
||||||
import { useFetchMyBonusInfoQuery } from '@/entities/bonus/api/bonus.api';
|
|
||||||
|
|
||||||
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
||||||
import { Button } from '@/shared/shadcn-ui/button';
|
import { Button } from '@/shared/shadcn-ui/button';
|
||||||
import {
|
import {
|
||||||
@ -16,11 +14,20 @@ import {
|
|||||||
|
|
||||||
import { TransactionsTable } from '@/widgets/transactions-table';
|
import { TransactionsTable } from '@/widgets/transactions-table';
|
||||||
|
|
||||||
|
// Sample customer data
|
||||||
|
const customerData = {
|
||||||
|
firstName: 'Алишер',
|
||||||
|
lastName: 'Рахмонов',
|
||||||
|
passportNumber: 'A12345678',
|
||||||
|
bonusPoints: 1250,
|
||||||
|
cardNumber: '5678-9012-3456-7890',
|
||||||
|
expiryDate: '12/2025',
|
||||||
|
registrationDate: '15.06.2020',
|
||||||
|
};
|
||||||
|
|
||||||
export function CustomerDashboard() {
|
export function CustomerDashboard() {
|
||||||
const { t } = useTextController();
|
const { t } = useTextController();
|
||||||
|
|
||||||
const { data, isLoading } = useFetchMyBonusInfoQuery({});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex min-h-screen flex-col'>
|
<div className='flex min-h-screen flex-col'>
|
||||||
<main className='flex-1 py-10'>
|
<main className='flex-1 py-10'>
|
||||||
@ -34,12 +41,8 @@ export function CustomerDashboard() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='mb-10 grid gap-3 md:grid-cols-3 md:gap-6'>
|
<div className='mb-10 grid gap-3 md:grid-cols-3 md:gap-6'>
|
||||||
|
{/* Bonus Card */}
|
||||||
<Card className='bg-gradient-to-br from-red-600 to-red-800 text-white'>
|
<Card className='bg-gradient-to-br from-red-600 to-red-800 text-white'>
|
||||||
{!data || isLoading ? (
|
|
||||||
// TODO: Bunyod please add loader here
|
|
||||||
<>Loader here</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className='flex items-center gap-2'>
|
<CardTitle className='flex items-center gap-2'>
|
||||||
<CreditCard className='h-5 w-5' />
|
<CreditCard className='h-5 w-5' />
|
||||||
@ -51,7 +54,9 @@ export function CustomerDashboard() {
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<div className='text-center'>
|
<div className='text-center'>
|
||||||
<p className='mb-2 text-4xl font-bold'>{data.bonuses}</p>
|
<p className='mb-2 text-4xl font-bold'>
|
||||||
|
{customerData.bonusPoints}
|
||||||
|
</p>
|
||||||
<p className='text-white/80'>
|
<p className='text-white/80'>
|
||||||
{t('customer.bonusCard.points')}
|
{t('customer.bonusCard.points')}
|
||||||
</p>
|
</p>
|
||||||
@ -59,19 +64,12 @@ export function CustomerDashboard() {
|
|||||||
<div className='mt-6 flex items-center justify-between'>
|
<div className='mt-6 flex items-center justify-between'>
|
||||||
<div className='flex items-center gap-1 text-sm text-white/80'>
|
<div className='flex items-center gap-1 text-sm text-white/80'>
|
||||||
<Clock className='h-4 w-4' />
|
<Clock className='h-4 w-4' />
|
||||||
<span>
|
<span>{t('customer.bonusCard.validUntil')}</span>
|
||||||
{t('customer.bonusCard.validUntil')}{' '}
|
|
||||||
{new Date(data.end_date).toLocaleDateString('en-GB')}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<ArrowUpRight className='h-5 w-5 text-white/60' />
|
<ArrowUpRight className='h-5 w-5 text-white/60' />
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* Bonus Card */}
|
|
||||||
{/* Customer Card */}
|
{/* Customer Card */}
|
||||||
<Card className='md:col-span-2'>
|
<Card className='md:col-span-2'>
|
||||||
<CardHeader className='pb-2'>
|
<CardHeader className='pb-2'>
|
||||||
@ -81,24 +79,22 @@ export function CustomerDashboard() {
|
|||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
{!data || isLoading ? (
|
|
||||||
// TODO: Bunyod please add loader here
|
|
||||||
<>Loader here</>
|
|
||||||
) : (
|
|
||||||
<div className='grid gap-6 md:grid-cols-2'>
|
<div className='grid gap-6 md:grid-cols-2'>
|
||||||
<div>
|
<div>
|
||||||
<div className='mb-4 space-y-1'>
|
<div className='mb-4 space-y-1'>
|
||||||
<p className='text-sm text-gray-500'>
|
<p className='text-sm text-gray-500'>
|
||||||
{t('customer.infoCard.regDateLabel')}
|
{t('customer.infoCard.regDateLabel')}
|
||||||
</p>
|
</p>
|
||||||
<p className='font-medium'>{data.fullname}</p>
|
<p className='font-medium'>
|
||||||
|
{customerData.firstName} {customerData.lastName}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className='space-y-1'>
|
<div className='space-y-1'>
|
||||||
<p className='text-sm text-gray-500'>
|
<p className='text-sm text-gray-500'>
|
||||||
{t('customer.infoCard.regDateLabel')}
|
{t('customer.infoCard.regDateLabel')}
|
||||||
</p>
|
</p>
|
||||||
<p className='font-medium'>
|
<p className='font-medium'>
|
||||||
{new Date(data.reg_date).toLocaleDateString('en-GB')}
|
{customerData.registrationDate}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -107,11 +103,16 @@ export function CustomerDashboard() {
|
|||||||
<p className='text-sm text-gray-500'>
|
<p className='text-sm text-gray-500'>
|
||||||
{t('customer.infoCard.cardNumberLabel')}
|
{t('customer.infoCard.cardNumberLabel')}
|
||||||
</p>
|
</p>
|
||||||
<p className='font-medium'>{data.cardno}</p>
|
<p className='font-medium'>{customerData.cardNumber}</p>
|
||||||
|
</div>
|
||||||
|
<div className='mb-4 space-y-1'>
|
||||||
|
<p className='text-sm text-gray-500'>
|
||||||
|
{t('customer.infoCard.expiryDateLabel')}
|
||||||
|
</p>
|
||||||
|
<p className='font-medium'>{customerData.expiryDate}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,14 +1,11 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { deleteCookie, getCookie } from 'cookies-next';
|
|
||||||
import { Building2, Fuel, User } from 'lucide-react';
|
import { Building2, Fuel, User } from 'lucide-react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useRouter, useSearchParams } from 'next/navigation';
|
|
||||||
|
|
||||||
import { LoginForm } from '@/features/auth/login-form';
|
import { LoginForm } from '@/features/auth/login-form';
|
||||||
|
|
||||||
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
||||||
import { Button } from '@/shared/shadcn-ui/button';
|
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
@ -42,13 +39,6 @@ const tabs = [
|
|||||||
|
|
||||||
export default function LoginPage() {
|
export default function LoginPage() {
|
||||||
const { t } = useTextController();
|
const { t } = useTextController();
|
||||||
const router = useRouter();
|
|
||||||
const searchParams = useSearchParams();
|
|
||||||
const defaultTab = searchParams.get('tab') || 'bonus';
|
|
||||||
|
|
||||||
const handleTabChange = (tabType: string) => {
|
|
||||||
router.push(`?tab=${tabType}`, undefined, { shallow: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex min-h-screen flex-col items-center justify-center'>
|
<div className='flex min-h-screen flex-col items-center justify-center'>
|
||||||
@ -65,12 +55,7 @@ export default function LoginPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='mx-auto max-w-lg'>
|
<div className='mx-auto max-w-lg'>
|
||||||
<Tabs
|
<Tabs defaultValue='bonus' className='w-full'>
|
||||||
defaultValue={defaultTab}
|
|
||||||
value={defaultTab}
|
|
||||||
onValueChange={handleTabChange}
|
|
||||||
className='w-full'
|
|
||||||
>
|
|
||||||
<TabsList className='mb-8 flex h-fit w-full flex-col sm:flex-row'>
|
<TabsList className='mb-8 flex h-fit w-full flex-col sm:flex-row'>
|
||||||
{tabs.map((tab) => {
|
{tabs.map((tab) => {
|
||||||
return (
|
return (
|
||||||
@ -86,45 +71,6 @@ export default function LoginPage() {
|
|||||||
</TabsList>
|
</TabsList>
|
||||||
|
|
||||||
{tabs.map((tab) => {
|
{tabs.map((tab) => {
|
||||||
const tabCookieName = `${tab.type}__token`;
|
|
||||||
|
|
||||||
const authenticationCookie = getCookie(tabCookieName);
|
|
||||||
|
|
||||||
if (authenticationCookie) {
|
|
||||||
return (
|
|
||||||
<TabsContent key={tab.label} value={tab.type}>
|
|
||||||
<Card>
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle>{t(tab.title)}</CardTitle>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent className='flex justify-center gap-2 space-y-4'>
|
|
||||||
<Link
|
|
||||||
href={
|
|
||||||
tab.type === 'bonus'
|
|
||||||
? '/customer-dashboard'
|
|
||||||
: '/corporate-dashboard'
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Button className='flex items-center'>
|
|
||||||
Открыть
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
<Button
|
|
||||||
variant='outline'
|
|
||||||
className='flex items-center gap-2'
|
|
||||||
onClick={() => {
|
|
||||||
deleteCookie(tabCookieName);
|
|
||||||
window.location.reload();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Выйти
|
|
||||||
</Button>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</TabsContent>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TabsContent key={tab.label} value={tab.type}>
|
<TabsContent key={tab.label} value={tab.type}>
|
||||||
<Card>
|
<Card>
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
|
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
|
||||||
import { toast } from 'sonner';
|
|
||||||
|
|
||||||
const baseQuery = fetchBaseQuery({
|
const baseQuery = fetchBaseQuery({
|
||||||
baseUrl: process.env.NEXT_PUBLIC_API_URL,
|
baseUrl: process.env.NEXT_PUBLIC_API_URL,
|
||||||
@ -16,25 +15,7 @@ export const TAGS = {
|
|||||||
|
|
||||||
export const baseAPI = createApi({
|
export const baseAPI = createApi({
|
||||||
reducerPath: 'baseAPI',
|
reducerPath: 'baseAPI',
|
||||||
baseQuery: async (args, api, extraOptions) => {
|
baseQuery,
|
||||||
const result = await baseQuery(args, api, extraOptions);
|
|
||||||
|
|
||||||
if (result.error) {
|
|
||||||
switch (result.error.status) {
|
|
||||||
case 401:
|
|
||||||
toast.error('Login credentials error');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 500:
|
|
||||||
toast.error('Server error, please try later');
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
tagTypes: Object.values(TAGS),
|
tagTypes: Object.values(TAGS),
|
||||||
endpoints: () => ({}),
|
endpoints: () => ({}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import { combineReducers } from '@reduxjs/toolkit';
|
import { combineReducers } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
import { loginAPI } from '@/entities/auth/api/login.api';
|
||||||
|
|
||||||
import { baseAPI } from '@/shared/api/base-api';
|
import { baseAPI } from '@/shared/api/base-api';
|
||||||
|
|
||||||
export const rootReducer = combineReducers({
|
export const rootReducer = combineReducers({
|
||||||
[baseAPI.reducerPath]: baseAPI.reducer,
|
[baseAPI.reducerPath]: baseAPI.reducer,
|
||||||
|
[loginAPI.reducerPath]: loginAPI.reducer,
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user