Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
fbffec54
Commit
fbffec54
authored
Sep 27, 2024
by
Max Alekseenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
improve login, fetch real data
parent
67acc9a4
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
128 additions
and
13 deletions
+128
-13
resources.ts
lib/api/resources.ts
+38
-1
rewards.tsx
lib/contexts/rewards.tsx
+38
-2
useNavItems.tsx
lib/hooks/useNavItems.tsx
+10
-6
fetchProxy.ts
nextjs/utils/fetchProxy.ts
+2
-1
rewards.ts
types/api/rewards.ts
+28
-0
RewardsDashboard.tsx
ui/pages/RewardsDashboard.tsx
+11
-2
RewardsDashboardCard.tsx
ui/rewards/RewardsDashboardCard.tsx
+1
-1
No files found.
lib/api/resources.ts
View file @
fbffec54
...
@@ -90,7 +90,15 @@ import type {
...
@@ -90,7 +90,15 @@ import type {
OptimismL2BatchBlocks
,
OptimismL2BatchBlocks
,
}
from
'
types/api/optimisticL2
'
;
}
from
'
types/api/optimisticL2
'
;
import
type
{
RawTracesResponse
}
from
'
types/api/rawTrace
'
;
import
type
{
RawTracesResponse
}
from
'
types/api/rawTrace
'
;
import
type
{
RewardsNonceResponse
,
RewardsCheckUserResponse
,
RewardsLoginResponse
}
from
'
types/api/rewards
'
;
import
type
{
RewardsNonceResponse
,
RewardsCheckUserResponse
,
RewardsLoginResponse
,
RewardsUserBalancesResponse
,
RewardsUserDailyCheckResponse
,
RewardsUserDailyClaimResponse
,
RewardsUserReferralsResponse
,
}
from
'
types/api/rewards
'
;
import
type
{
SearchRedirectResult
,
SearchResult
,
SearchResultFilters
,
SearchResultItem
}
from
'
types/api/search
'
;
import
type
{
SearchRedirectResult
,
SearchResult
,
SearchResultFilters
,
SearchResultItem
}
from
'
types/api/search
'
;
import
type
{
ShibariumWithdrawalsResponse
,
ShibariumDepositsResponse
}
from
'
types/api/shibarium
'
;
import
type
{
ShibariumWithdrawalsResponse
,
ShibariumDepositsResponse
}
from
'
types/api/shibarium
'
;
import
type
{
HomeStats
}
from
'
types/api/stats
'
;
import
type
{
HomeStats
}
from
'
types/api/stats
'
;
...
@@ -337,6 +345,31 @@ export const RESOURCES = {
...
@@ -337,6 +345,31 @@ export const RESOURCES = {
endpoint
:
getFeaturePayload
(
config
.
features
.
rewards
)?.
api
.
endpoint
,
endpoint
:
getFeaturePayload
(
config
.
features
.
rewards
)?.
api
.
endpoint
,
basePath
:
getFeaturePayload
(
config
.
features
.
rewards
)?.
api
.
basePath
,
basePath
:
getFeaturePayload
(
config
.
features
.
rewards
)?.
api
.
basePath
,
},
},
rewards_logout
:
{
path
:
'
/api/v1/auth/logout
'
,
endpoint
:
getFeaturePayload
(
config
.
features
.
rewards
)?.
api
.
endpoint
,
basePath
:
getFeaturePayload
(
config
.
features
.
rewards
)?.
api
.
basePath
,
},
rewards_user_balances
:
{
path
:
'
/api/v1/user/balances
'
,
endpoint
:
getFeaturePayload
(
config
.
features
.
rewards
)?.
api
.
endpoint
,
basePath
:
getFeaturePayload
(
config
.
features
.
rewards
)?.
api
.
basePath
,
},
rewards_user_daily_check
:
{
path
:
'
/api/v1/user/daily/check
'
,
endpoint
:
getFeaturePayload
(
config
.
features
.
rewards
)?.
api
.
endpoint
,
basePath
:
getFeaturePayload
(
config
.
features
.
rewards
)?.
api
.
basePath
,
},
rewards_user_daily_claim
:
{
path
:
'
/api/v1/user/daily/claim
'
,
endpoint
:
getFeaturePayload
(
config
.
features
.
rewards
)?.
api
.
endpoint
,
basePath
:
getFeaturePayload
(
config
.
features
.
rewards
)?.
api
.
basePath
,
},
rewards_user_referrals
:
{
path
:
'
/api/v1/user/referrals
'
,
endpoint
:
getFeaturePayload
(
config
.
features
.
rewards
)?.
api
.
endpoint
,
basePath
:
getFeaturePayload
(
config
.
features
.
rewards
)?.
api
.
basePath
,
},
// BLOCKS, TXS
// BLOCKS, TXS
blocks
:
{
blocks
:
{
...
@@ -1191,6 +1224,10 @@ Q extends 'withdrawals_counters' ? WithdrawalsCounters :
...
@@ -1191,6 +1224,10 @@ Q extends 'withdrawals_counters' ? WithdrawalsCounters :
Q
extends
'
rewards_nonce
'
?
RewardsNonceResponse
:
Q
extends
'
rewards_nonce
'
?
RewardsNonceResponse
:
Q
extends
'
rewards_check_user
'
?
RewardsCheckUserResponse
:
Q
extends
'
rewards_check_user
'
?
RewardsCheckUserResponse
:
Q
extends
'
rewards_login
'
?
RewardsLoginResponse
:
Q
extends
'
rewards_login
'
?
RewardsLoginResponse
:
Q
extends
'
rewards_user_balances
'
?
RewardsUserBalancesResponse
:
Q
extends
'
rewards_user_daily_check
'
?
RewardsUserDailyCheckResponse
:
Q
extends
'
rewards_user_daily_claim
'
?
RewardsUserDailyClaimResponse
:
Q
extends
'
rewards_user_referrals
'
?
RewardsUserReferralsResponse
:
never
;
never
;
/* eslint-enable @typescript-eslint/indent */
/* eslint-enable @typescript-eslint/indent */
...
...
lib/contexts/rewards.tsx
View file @
fbffec54
import
{
useBoolean
}
from
'
@chakra-ui/react
'
;
import
{
useBoolean
}
from
'
@chakra-ui/react
'
;
import
React
,
{
createContext
,
useContext
,
useMemo
}
from
'
react
'
;
import
React
,
{
createContext
,
useContext
,
useEffect
,
useMemo
}
from
'
react
'
;
import
type
{
RewardsUserBalancesResponse
,
RewardsUserDailyCheckResponse
}
from
'
types/api/rewards
'
;
import
config
from
'
configs/app
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
*
as
cookies
from
'
lib/cookies
'
;
type
Props
=
{
type
Props
=
{
children
:
React
.
ReactNode
;
children
:
React
.
ReactNode
;
...
@@ -9,22 +15,52 @@ type TRewardsContext = {
...
@@ -9,22 +15,52 @@ type TRewardsContext = {
isLoginModalOpen
:
boolean
;
isLoginModalOpen
:
boolean
;
openLoginModal
:
()
=>
void
;
openLoginModal
:
()
=>
void
;
closeLoginModal
:
()
=>
void
;
closeLoginModal
:
()
=>
void
;
balances
:
RewardsUserBalancesResponse
|
undefined
;
dailyReward
:
RewardsUserDailyCheckResponse
|
undefined
;
isLogedIn
:
boolean
;
}
}
const
RewardsContext
=
createContext
<
TRewardsContext
>
({
const
RewardsContext
=
createContext
<
TRewardsContext
>
({
isLoginModalOpen
:
false
,
isLoginModalOpen
:
false
,
openLoginModal
:
()
=>
{},
openLoginModal
:
()
=>
{},
closeLoginModal
:
()
=>
{},
closeLoginModal
:
()
=>
{},
balances
:
undefined
,
dailyReward
:
undefined
,
isLogedIn
:
false
,
});
});
export
function
RewardsContextProvider
({
children
}:
Props
)
{
export
function
RewardsContextProvider
({
children
}:
Props
)
{
const
apiToken
=
cookies
.
get
(
cookies
.
NAMES
.
REWARDS_API_TOKEN
);
const
apiQueryOptions
=
{
queryOptions
:
{
enabled
:
Boolean
(
apiToken
)
&&
config
.
features
.
rewards
.
isEnabled
,
},
fetchParams
:
{
headers
:
{
Authorization
:
`Bearer
${
apiToken
}
`
,
},
},
};
const
[
isLoginModalOpen
,
setIsLoginModalOpen
]
=
useBoolean
(
false
);
const
[
isLoginModalOpen
,
setIsLoginModalOpen
]
=
useBoolean
(
false
);
const
balancesQuery
=
useApiQuery
(
'
rewards_user_balances
'
,
apiQueryOptions
);
const
dailyRewardQuery
=
useApiQuery
(
'
rewards_user_daily_check
'
,
apiQueryOptions
);
useEffect
(()
=>
{
if
(
apiToken
&&
balancesQuery
.
error
?.
status
===
401
)
{
cookies
.
set
(
cookies
.
NAMES
.
REWARDS_API_TOKEN
,
''
);
}
},
[
balancesQuery
.
error
,
apiToken
]);
const
value
=
useMemo
(()
=>
({
const
value
=
useMemo
(()
=>
({
isLoginModalOpen
,
isLoginModalOpen
,
openLoginModal
:
setIsLoginModalOpen
.
on
,
openLoginModal
:
setIsLoginModalOpen
.
on
,
closeLoginModal
:
setIsLoginModalOpen
.
off
,
closeLoginModal
:
setIsLoginModalOpen
.
off
,
}),
[
isLoginModalOpen
,
setIsLoginModalOpen
]);
balances
:
balancesQuery
.
data
,
dailyReward
:
dailyRewardQuery
.
data
,
isLogedIn
:
Boolean
(
apiToken
),
}),
[
isLoginModalOpen
,
setIsLoginModalOpen
,
balancesQuery
.
data
,
dailyRewardQuery
.
data
,
apiToken
]);
return
(
return
(
<
RewardsContext
.
Provider
value=
{
value
}
>
<
RewardsContext
.
Provider
value=
{
value
}
>
...
...
lib/hooks/useNavItems.tsx
View file @
fbffec54
...
@@ -25,7 +25,11 @@ export function isInternalItem(item: NavItem): item is NavItemInternal {
...
@@ -25,7 +25,11 @@ export function isInternalItem(item: NavItem): item is NavItemInternal {
export
default
function
useNavItems
():
ReturnType
{
export
default
function
useNavItems
():
ReturnType
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
pathname
=
router
.
pathname
;
const
pathname
=
router
.
pathname
;
const
{
openLoginModal
:
openRewardsLoginModal
}
=
useRewardsContext
();
const
{
openLoginModal
:
openRewardsLoginModal
,
balances
:
rewardsBalances
,
isLogedIn
:
isLoggedInToRewards
,
}
=
useRewardsContext
();
return
React
.
useMemo
(()
=>
{
return
React
.
useMemo
(()
=>
{
let
blockchainNavItems
:
Array
<
NavItem
>
|
Array
<
Array
<
NavItem
>>
=
[];
let
blockchainNavItems
:
Array
<
NavItem
>
|
Array
<
Array
<
NavItem
>>
=
[];
...
@@ -268,11 +272,11 @@ export default function useNavItems(): ReturnType {
...
@@ -268,11 +272,11 @@ export default function useNavItems(): ReturnType {
const
accountNavItems
:
ReturnType
[
'
accountNavItems
'
]
=
[
const
accountNavItems
:
ReturnType
[
'
accountNavItems
'
]
=
[
config
.
features
.
rewards
.
isEnabled
?
{
config
.
features
.
rewards
.
isEnabled
?
{
text
:
'
Merits
'
,
text
:
rewardsBalances
?.
total
?
`
${
rewardsBalances
?.
total
}
Merits
` :
'Merits',
// nextRoute: { pathname: '/account/rewards' as const }
,
nextRoute: isLoggedInToRewards ? { pathname: '/account/rewards' as const } : undefined
,
onClick
:
openRewardsLoginModal
,
onClick:
isLoggedInToRewards ? undefined :
openRewardsLoginModal,
icon: 'merits',
icon: 'merits',
// isActive:
pathname === '/account/rewards',
isActive: isLoggedInToRewards &&
pathname === '/account/rewards',
} : null,
} : null,
{
{
text: 'Watch list',
text: 'Watch list',
...
@@ -314,5 +318,5 @@ export default function useNavItems(): ReturnType {
...
@@ -314,5 +318,5 @@ export default function useNavItems(): ReturnType {
};
};
return { mainNavItems, accountNavItems, profileItem };
return { mainNavItems, accountNavItems, profileItem };
},
[
pathname
,
openRewardsLoginModal
]);
}, [ pathname, openRewardsLoginModal
, rewardsBalances, isLoggedInToRewards
]);
}
}
nextjs/utils/fetchProxy.ts
View file @
fbffec54
...
@@ -23,7 +23,8 @@ export default function fetchFactory(
...
@@ -23,7 +23,8 @@ export default function fetchFactory(
cookie
:
apiToken
?
`
${
cookies
.
NAMES
.
API_TOKEN
}
=
${
apiToken
}
`
:
''
,
cookie
:
apiToken
?
`
${
cookies
.
NAMES
.
API_TOKEN
}
=
${
apiToken
}
`
:
''
,
...
_pick
(
_req
.
headers
,
[
...
_pick
(
_req
.
headers
,
[
'
x-csrf-token
'
,
'
x-csrf-token
'
,
'
Authorization
'
,
'
Authorization
'
,
// the old value, just in case
'
authorization
'
,
// Node.js automatically lowercases headers
// feature flags
// feature flags
'
updated-gas-oracle
'
,
'
updated-gas-oracle
'
,
])
as
Record
<
string
,
string
|
undefined
>
,
])
as
Record
<
string
,
string
|
undefined
>
,
...
...
types/api/rewards.ts
View file @
fbffec54
...
@@ -10,3 +10,31 @@ export type RewardsLoginResponse = {
...
@@ -10,3 +10,31 @@ export type RewardsLoginResponse = {
created
:
boolean
;
created
:
boolean
;
token
:
string
;
token
:
string
;
};
};
export
type
RewardsUserBalancesResponse
=
{
total
:
string
;
staked
:
string
;
unstaked
:
string
;
total_staking_rewards
:
string
;
total_referral_rewards
:
string
;
pending_referral_rewards
:
string
;
};
export
type
RewardsUserDailyCheckResponse
=
{
available
:
boolean
;
daily_reward
:
string
;
pending_referral_rewards
:
string
;
date
:
string
;
reset_at
:
string
;
};
export
type
RewardsUserDailyClaimResponse
=
{
daily_reward
:
string
;
pending_referral_rewards
:
string
;
};
export
type
RewardsUserReferralsResponse
=
{
code
:
string
;
link
:
string
;
referrals
:
string
;
};
ui/pages/RewardsDashboard.tsx
View file @
fbffec54
import
{
Button
,
Flex
,
Text
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
Button
,
Flex
,
Text
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
useRewardsContext
}
from
'
lib/contexts/rewards
'
;
import
CopyField
from
'
ui/rewards/CopyField
'
;
import
CopyField
from
'
ui/rewards/CopyField
'
;
import
RewardsDashboardCard
from
'
ui/rewards/RewardsDashboardCard
'
;
import
RewardsDashboardCard
from
'
ui/rewards/RewardsDashboardCard
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
...
@@ -8,6 +10,13 @@ import LinkExternal from 'ui/shared/links/LinkExternal';
...
@@ -8,6 +10,13 @@ import LinkExternal from 'ui/shared/links/LinkExternal';
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
const
RewardsDashboard
=
()
=>
{
const
RewardsDashboard
=
()
=>
{
const
router
=
useRouter
();
const
{
balances
,
dailyReward
,
isLogedIn
}
=
useRewardsContext
();
if
(
!
isLogedIn
)
{
router
.
replace
({
pathname
:
'
/
'
},
undefined
,
{
shallow
:
true
});
}
return
(
return
(
<>
<>
<
PageTitle
<
PageTitle
...
@@ -26,8 +35,8 @@ const RewardsDashboard = () => {
...
@@ -26,8 +35,8 @@ const RewardsDashboard = () => {
<
Flex
gap=
{
6
}
>
<
Flex
gap=
{
6
}
>
<
RewardsDashboardCard
<
RewardsDashboardCard
description=
"Claim your daily merits and any merits received from referrals."
description=
"Claim your daily merits and any merits received from referrals."
values=
{
[
{
label
:
'
Total balance
'
,
value
:
250
}
]
}
values=
{
[
{
label
:
'
Total balance
'
,
value
:
balances
?.
total
}
]
}
contentAfter=
{
<
Button
>
Claim
X
Merits
</
Button
>
}
contentAfter=
{
<
Button
>
Claim
{
dailyReward
?.
daily_reward
}
Merits
</
Button
>
}
/>
/>
<
RewardsDashboardCard
<
RewardsDashboardCard
title=
"Title"
title=
"Title"
...
...
ui/rewards/RewardsDashboardCard.tsx
View file @
fbffec54
...
@@ -7,7 +7,7 @@ import AvailableSoonLabel from './AvailableSoonLabel';
...
@@ -7,7 +7,7 @@ import AvailableSoonLabel from './AvailableSoonLabel';
type
Value
=
{
type
Value
=
{
label
:
string
;
label
:
string
;
value
:
number
;
value
:
number
|
string
|
undefined
;
type
?:
'
percentages
'
;
type
?:
'
percentages
'
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment