Browse Source

ui(web): improve dashboard ui

pull/8/head
isra el 2 years ago
parent
commit
4d1f2e144e
  1. 90
      web/components/dashboard/SendSMS.tsx
  2. 4
      web/components/dashboard/UserStats.tsx
  3. 9
      web/components/dashboard/UserStatsCard.tsx
  4. 86
      web/pages/dashboard.tsx
  5. 4
      web/services/types.ts

90
web/components/dashboard/SendSMS.tsx

@ -1,20 +1,11 @@
import { import {
Box, Box,
Button, Button,
Flex,
FormLabel, FormLabel,
Input, Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Select, Select,
Spinner, Spinner,
Textarea, Textarea,
useDisclosure,
useToast, useToast,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { useState } from 'react' import { useState } from 'react'
@ -50,22 +41,22 @@ export const SendSMSForm = ({ deviceList, formData, handleChange }) => {
</Select> </Select>
</Box> </Box>
<Box> <Box>
<FormLabel htmlFor='receivers'>Receiver</FormLabel>
<FormLabel htmlFor='recipient'>Recipient</FormLabel>
<Input <Input
placeholder='receiver'
name='receivers'
placeholder='recipient'
name='recipients'
onChange={handleChange} onChange={handleChange}
value={formData.receivers}
value={formData.recipients}
type='tel' type='tel'
/> />
</Box> </Box>
<Box> <Box>
<FormLabel htmlFor='smsBody'>SMS Body</FormLabel>
<FormLabel htmlFor='message'>Message</FormLabel>
<Textarea <Textarea
id='smsBody'
name='smsBody'
id='message'
name='message'
onChange={handleChange} onChange={handleChange}
value={formData.smsBody}
value={formData.message}
/> />
</Box> </Box>
</> </>
@ -73,7 +64,6 @@ export const SendSMSForm = ({ deviceList, formData, handleChange }) => {
} }
export default function SendSMS() { export default function SendSMS() {
const { isOpen, onOpen, onClose } = useDisclosure()
const deviceList = useSelector(selectDeviceList) const deviceList = useSelector(selectDeviceList)
const toast = useToast() const toast = useToast()
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
@ -82,16 +72,16 @@ export default function SendSMS() {
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
device: '', device: '',
receivers: '',
smsBody: '',
recipients: '',
message: '',
}) })
const handSend = (e) => { const handSend = (e) => {
e.preventDefault() e.preventDefault()
const { device: deviceId, receivers, smsBody } = formData
const receiversArray = receivers.replace(' ', '').split(',')
const { device: deviceId, recipients, message } = formData
const recipientsArray = recipients.replace(' ', '').split(',')
if (!deviceId || !receivers || !smsBody) {
if (!deviceId || !recipients || !message) {
toast({ toast({
title: 'Please fill all fields', title: 'Please fill all fields',
status: 'error', status: 'error',
@ -99,7 +89,7 @@ export default function SendSMS() {
return return
} }
for (let receiver of receiversArray) {
for (let recipient of recipientsArray) {
// TODO: validate phone numbers // TODO: validate phone numbers
} }
@ -107,8 +97,8 @@ export default function SendSMS() {
sendSMS({ sendSMS({
deviceId, deviceId,
payload: { payload: {
receivers: receiversArray,
smsBody,
recipients: recipientsArray,
message,
}, },
}) })
) )
@ -123,39 +113,23 @@ export default function SendSMS() {
return ( return (
<> <>
<Flex justifyContent='flex-end' marginBottom={20}>
<Button bg={'blue.400'} color={'white'} onClick={onOpen}>
Send SMS
</Button>
</Flex>
<Box maxW='xl' mx={'auto'} pt={5} px={{ base: 2, sm: 12, md: 17 }}>
<SendSMSForm
deviceList={deviceList}
formData={formData}
handleChange={handleChange}
/>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Send SMS</ModalHeader>
<ModalCloseButton />
<ModalBody>
<SendSMSForm
deviceList={deviceList}
formData={formData}
handleChange={handleChange}
/>
</ModalBody>
<ModalFooter>
<Button variant='ghost' mr={3} onClick={onClose}>
Close
</Button>
<Button
variant='outline'
colorScheme='blue'
onClick={handSend}
disabled={sendingSMS}
>
{sendingSMS ? <Spinner size='md' /> : 'Send'}
</Button>
</ModalFooter>
</ModalContent>
</Modal>
<Button
variant='outline'
colorScheme='blue'
onClick={handSend}
disabled={sendingSMS}
marginTop={3}
>
{sendingSMS ? <Spinner size='md' /> : 'Send'}
</Button>
</Box>
</> </>
) )
} }

4
web/components/dashboard/UserStats.tsx

@ -28,8 +28,8 @@ const UserStats = () => {
<Box maxW='7xl' mx={'auto'} pt={5} px={{ base: 2, sm: 12, md: 17 }}> <Box maxW='7xl' mx={'auto'} pt={5} px={{ base: 2, sm: 12, md: 17 }}>
<SimpleGrid columns={{ base: 1, md: 2 }}> <SimpleGrid columns={{ base: 1, md: 2 }}>
<chakra.h1 <chakra.h1
textAlign={'center'}
fontSize={'4xl'}
// textAlign={'center'}
fontSize={'2xl'}
py={10} py={10}
fontWeight={'bold'} fontWeight={'bold'}
> >

9
web/components/dashboard/UserStatsCard.tsx

@ -10,20 +10,21 @@ export default function UserStatsCard({ ...props }) {
const { title, stat } = props const { title, stat } = props
return ( return (
<Stat <Stat
px={{ base: 4, md: 8 }}
py={'5'}
px={{ base: 2, md: 4 }}
py={'3'}
shadow={'xl'} shadow={'xl'}
border={'1px solid'} border={'1px solid'}
borderColor={useColorModeValue('gray.800', 'gray.500')} borderColor={useColorModeValue('gray.800', 'gray.500')}
rounded={'lg'} rounded={'lg'}
style={{ style={{
height: '90px'
height: '90px',
}} }}
alignContent={'center'}
> >
<StatLabel fontWeight={'medium'} isTruncated> <StatLabel fontWeight={'medium'} isTruncated>
{title} {title}
</StatLabel> </StatLabel>
<StatNumber fontSize={'md'} fontWeight={'bold'}>
<StatNumber fontSize={'md'} fontWeight={'medium'}>
{stat} {stat}
</StatNumber> </StatNumber>
</Stat> </Stat>

86
web/pages/dashboard.tsx

@ -1,4 +1,13 @@
import { Box, SimpleGrid, useToast } from '@chakra-ui/react'
import {
Box,
SimpleGrid,
Tab,
TabList,
TabPanel,
TabPanels,
Tabs,
useToast,
} from '@chakra-ui/react'
import ApiKeyList from '../components/dashboard/ApiKeyList' import ApiKeyList from '../components/dashboard/ApiKeyList'
import UserStats from '../components/dashboard/UserStats' import UserStats from '../components/dashboard/UserStats'
import GenerateApiKey from '../components/dashboard/GenerateApiKey' import GenerateApiKey from '../components/dashboard/GenerateApiKey'
@ -6,7 +15,7 @@ import DeviceList from '../components/dashboard/DeviceList'
import { useSelector } from 'react-redux' import { useSelector } from 'react-redux'
import { selectAuthUser } from '../store/authSlice' import { selectAuthUser } from '../store/authSlice'
import Router from 'next/router' import Router from 'next/router'
import { useEffect } from 'react'
import { useEffect, useState } from 'react'
import SendSMS from '../components/dashboard/SendSMS' import SendSMS from '../components/dashboard/SendSMS'
import ErrorBoundary from '../components/ErrorBoundary' import ErrorBoundary from '../components/ErrorBoundary'
import dynamic from 'next/dynamic' import dynamic from 'next/dynamic'
@ -31,25 +40,64 @@ export default function Dashboard() {
Router.push('/login') Router.push('/login')
} }
}, [authUser, toast]) }, [authUser, toast])
return (
<>
<NoSSRAnimatedWrapper>
<UserStats />
<DashboardTabView />
</NoSSRAnimatedWrapper>
</>
)
}
const DashboardTabView = () => {
const [tabIndex, setTabIndex] = useState(1)
return ( return (
<NoSSRAnimatedWrapper>
<UserStats />
<Box maxW='7xl' mx={'auto'} pt={5} px={{ base: 2, sm: 12, md: 17 }}>
<SimpleGrid columns={{ base: 1, md: 2 }} spacing={{ base: 5, lg: 8 }}>
<Box backdropBlur='2xl' borderWidth='0px' borderRadius='lg'>
<GenerateApiKey />
<ErrorBoundary>
<ApiKeyList />
</ErrorBoundary>
</Box>
<Box backdropBlur='2xl' borderWidth='0px' borderRadius='lg'>
<Box maxW='7xl' mx={'auto'} pt={5} px={{ base: 2, sm: 12, md: 17 }}>
<Tabs isLazy={false} index={tabIndex} onChange={setTabIndex}>
<TabList>
{/* <Tab>Get Started</Tab> */}
<Tab>API Key and Devices</Tab>
<Tab>Send SMS</Tab>
<Tab>Receive SMS</Tab>
</TabList>
<TabPanels>
{/* <TabPanel>
Get Started
</TabPanel> */}
<TabPanel>
<APIKeyAndDevices />
</TabPanel>
<TabPanel>
<SendSMS /> <SendSMS />
<ErrorBoundary>
<DeviceList />
</ErrorBoundary>
</Box>
</SimpleGrid>
</TabPanel>
<TabPanel>Receive SMS</TabPanel>
</TabPanels>
</Tabs>
</Box>
)
}
const APIKeyAndDevices = () => {
return (
<Box maxW='7xl' mx={'auto'} pt={5} px={{ base: 2, sm: 12, md: 17 }}>
<Box maxW='xl' mx={'auto'} pt={5} px={{ base: 2, sm: 12, md: 17 }}>
<GenerateApiKey />
</Box> </Box>
</NoSSRAnimatedWrapper>
<SimpleGrid columns={{ base: 1, md: 2 }} spacing={{ base: 5, lg: 8 }}>
<Box backdropBlur='2xl' borderWidth='0px' borderRadius='lg'>
<ErrorBoundary>
<ApiKeyList />
</ErrorBoundary>
</Box>
<Box backdropBlur='2xl' borderWidth='0px' borderRadius='lg'>
{/* <SendSMS /> */}
<ErrorBoundary>
<DeviceList />
</ErrorBoundary>
</Box>
</SimpleGrid>
</Box>
) )
} }

4
web/services/types.ts

@ -50,8 +50,8 @@ export interface CurrentUserResponse extends BaseResponse {
} }
export interface SendSMSRequestPayload { export interface SendSMSRequestPayload {
receivers: string[]
smsBody: string
recipients: string[]
message: string
} }
export interface ApiKeyEntity { export interface ApiKeyEntity {

Loading…
Cancel
Save