@@ -3,7 +3,7 @@ import { useMutation, useQuery } from "react-query"
33import { useRouter } from "next/router"
44import { AiOutlineLogout , AiOutlineSetting , AiOutlineFileText , AiOutlineAlert , AiOutlinePlus , AiOutlineComment , AiOutlineCode , AiOutlineRight , AiOutlineDown , AiOutlineFile , AiOutlineQuestion , AiOutlineQuestionCircle } from 'react-icons/ai'
55import { signout , signOut } from "next-auth/client"
6- import { Anchor , AppShell , Avatar , Badge , Box , Button , Code , Group , Header , Menu , Modal , Navbar , NavLink , ScrollArea , Select , Space , Stack , Switch , Text , TextInput , Title } from "@mantine/core"
6+ import { Anchor , AppShell , Avatar , Badge , Box , Button , Code , Grid , Group , Header , List , Menu , Modal , Navbar , NavLink , Paper , Progress , ScrollArea , Select , Space , Stack , Switch , Text , TextInput , Title } from "@mantine/core"
77import Link from "next/link"
88import type { ProjectServerSideProps } from "../pages/dashboard/project/[projectId]/settings"
99import { modals } from "@mantine/modals"
@@ -13,6 +13,8 @@ import { apiClient } from "../utils.client"
1313import { useForm } from "react-hook-form"
1414import { MainLayoutData } from "../service/viewData.service"
1515import { Head } from "./Head"
16+ import dayjs from "dayjs"
17+ import { usageLimitation } from "../config.common"
1618
1719// From https://stackoverflow.com/questions/46155/how-to-validate-an-email-address-in-javascript
1820function validateEmail ( email ) {
@@ -55,6 +57,25 @@ export function MainLayout(props: {
5557 } ,
5658 } )
5759
60+ const downgradePlanMutation = useMutation ( async ( ) => {
61+ await apiClient . delete ( '/subscription' )
62+ } , {
63+ onSuccess ( ) {
64+ notifications . show ( {
65+ title : 'Success' ,
66+ message : 'Downgrade success' ,
67+ color : 'green'
68+ } )
69+ } ,
70+ onError ( ) {
71+ notifications . show ( {
72+ title : 'Error' ,
73+ message :
'Something went wrong, please contact [email protected] ' , 74+ color : 'red'
75+ } )
76+ }
77+ } )
78+
5879 const updateNewCommentNotification = useMutation ( updateUserSettings , {
5980 onSuccess ( ) {
6081 notifications . show ( {
@@ -209,11 +230,14 @@ export function MainLayout(props: {
209230 } , [ ] )
210231
211232 const badge = React . useMemo ( ( ) => {
212- if ( ! props . config . isHosted ) {
213- return < Badge color = "green" size = "xs" > OSS </ Badge >
233+ if ( props . subscription . isActived ) {
234+ return < Badge color = "green" size = "xs" > PRO </ Badge >
214235 }
215236
216- return < Badge color = "green" size = "xs" > PRO</ Badge >
237+ if ( props . config . isHosted ) {
238+ return < Badge color = "gray" size = "xs" > OSS</ Badge >
239+ }
240+ return < Badge color = "green" size = "xs" > FREE</ Badge >
217241 } , [ ] )
218242
219243 const header = React . useMemo ( ( ) => {
@@ -242,12 +266,43 @@ export function MainLayout(props: {
242266 < Group spacing = { 4 } >
243267 < Button onClick = { _ => {
244268 openUserModal ( )
245- } } size = "xs" rightIcon = { < AiOutlineRight /> } variant = 'subtle' > { props . session . user . name } </ Button >
269+ } } size = "xs" rightIcon = { < AiOutlineRight /> } variant = 'subtle' > { props . session . user . name } { badge } </ Button >
246270 </ Group >
247271 </ Group >
248272 )
249273 } , [ ] )
250274
275+ const usageBoard = React . useMemo ( ( ) => {
276+ return (
277+ < >
278+ < Text size = "sm" weight = { 900 } >
279+ Usage (per month)
280+ </ Text >
281+ < Stack spacing = { 4 } >
282+ < Group spacing = { 4 } >
283+ < Text weight = { 500 } size = "sm" > Sites:</ Text >
284+ < Text size = 'sm' >
285+ { `${ props . usage . projectCount } / ${ usageLimitation [ 'create_site' ] } ` }
286+ </ Text >
287+ </ Group >
288+
289+ < Group spacing = { 4 } >
290+ < Text weight = { 500 } size = "sm" > Approve comments:</ Text >
291+ < Text size = 'sm' >
292+ { `${ props . usage . approveCommentUsage } / ${ usageLimitation [ 'approve_comment' ] } ` }
293+ </ Text >
294+ </ Group >
295+ < Group spacing = { 4 } >
296+ < Text weight = { 500 } size = "sm" > Quick Approve:</ Text >
297+ < Text size = 'sm' >
298+ { `${ props . usage . quickApproveUsage } / ${ usageLimitation [ 'quick_approve' ] } ` }
299+ </ Text >
300+ </ Group >
301+ </ Stack >
302+ </ >
303+ )
304+ } , [ ] )
305+
251306 return (
252307 < >
253308 < Head title = { `${ props . project . title } - Cusdis` } />
@@ -273,7 +328,7 @@ export function MainLayout(props: {
273328 }
274329 } }
275330 >
276- < Modal opened = { isUserPannelOpen } onClose = { closeUserModal }
331+ < Modal opened = { isUserPannelOpen } size = "lg" onClose = { closeUserModal }
277332 title = "User Settings"
278333 >
279334 < Stack >
@@ -298,11 +353,81 @@ export function MainLayout(props: {
298353 < Text weight = { 500 } size = "sm" > Display name</ Text >
299354 < TextInput placeholder = { props . userInfo . name } { ...userSettingsForm . register ( "displayName" ) } size = "sm" />
300355 </ Stack >
301- { /* <Stack spacing={8}>
302- <Text weight={500} size="sm">Subscription </Text>
303- <Text size="sm">Current plan: {badge}</Text>
304- <Anchor size="sm">Manage subscription</Anchor>
305- </Stack> */ }
356+ { props . config . checkout . enabled && (
357+ < >
358+ { usageBoard }
359+ < Stack spacing = { 8 } >
360+ < Text weight = { 900 } size = "sm" > Subscription </ Text >
361+ < Grid >
362+ < Grid . Col span = { 6 } >
363+ < Paper sx = { theme => ( {
364+ border : '1px solid #eaeaea' ,
365+ padding : theme . spacing . md
366+ } ) } >
367+ < Stack >
368+ < Title order = { 4 } >
369+ Free
370+ </ Title >
371+ < List size = 'sm' sx = { {
372+ } } >
373+ < List . Item >
374+ Up to 1 site
375+ </ List . Item >
376+ < List . Item >
377+ 10 Quick Approve / month
378+ </ List . Item >
379+ < List . Item >
380+ 100 approved comments / month
381+ </ List . Item >
382+ </ List >
383+ { ! props . subscription . isActived || props . subscription . status === 'cancelled' ? (
384+ < Button disabled size = "xs" > Current plan</ Button >
385+ ) : (
386+ < Button size = "xs" variant = { 'outline' } loading = { downgradePlanMutation . isLoading } onClick = { _ => {
387+ if ( window . confirm ( 'Are you sure to downgrade?' ) ) {
388+ downgradePlanMutation . mutate ( )
389+ }
390+ } } > Downgrade</ Button >
391+ ) }
392+ </ Stack >
393+ </ Paper >
394+ </ Grid . Col >
395+ < Grid . Col span = { 6 } >
396+ < Paper sx = { theme => ( {
397+ border : '1px solid #eaeaea' ,
398+ padding : theme . spacing . md
399+ } ) } >
400+ < Stack >
401+ < Title order = { 4 } >
402+ Pro
403+ </ Title >
404+ < List size = 'sm' sx = { {
405+ } } >
406+ < List . Item >
407+ Unlimited sites
408+ </ List . Item >
409+ < List . Item >
410+ Unlimited Quick Approve
411+ </ List . Item >
412+ < List . Item >
413+ Unlimited approved comments
414+ </ List . Item >
415+ </ List >
416+ { props . subscription . isActived ? (
417+ < >
418+ < Button size = "xs" component = "a" href = { props . subscription . updatePaymentMethodUrl } > Manage payment method</ Button >
419+ { props . subscription . status === 'cancelled' && ( < Text size = 'xs' align = 'center' > Expire on { dayjs ( props . subscription . endAt ) . format ( 'YYYY/MM/DD' ) } </ Text > ) }
420+ </ >
421+ ) : (
422+ < Button size = 'xs' component = "a" href = { `${ props . config . checkout . url } ?checkout[custom][user_id]=${ props . session . uid } ` } > Upgrade $5/month</ Button >
423+ ) }
424+ </ Stack >
425+ </ Paper >
426+ </ Grid . Col >
427+ </ Grid >
428+ </ Stack >
429+ </ >
430+ ) }
306431 < Button loading = { updateUserSettingsMutation . isLoading } onClick = { onClickSaveUserSettings } > Save</ Button >
307432 < Button onClick = { _ => signOut ( ) } variant = { 'outline' } color = 'red' >
308433 Logout
0 commit comments