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 {
Box,
Button,
Flex,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Select,
Spinner,
Textarea,
useDisclosure,
useToast,
} from '@chakra-ui/react'
import { useState } from 'react'
@ -50,22 +41,22 @@ export const SendSMSForm = ({ deviceList, formData, handleChange }) => {
</Select>
</Box>
<Box>
<FormLabel htmlFor='receivers'>Receiver</FormLabel>
<FormLabel htmlFor='recipient'>Recipient</FormLabel>
<Input
placeholder='receiver'
name='receivers'
placeholder='recipient'
name='recipients'
onChange={handleChange}
value={formData.receivers}
value={formData.recipients}
type='tel'
/>
</Box>
<Box>
<FormLabel htmlFor='smsBody'>SMS Body</FormLabel>
<FormLabel htmlFor='message'>Message</FormLabel>
<Textarea
id='smsBody'
name='smsBody'
id='message'
name='message'
onChange={handleChange}
value={formData.smsBody}
value={formData.message}
/>
</Box>
</>
@ -73,7 +64,6 @@ export const SendSMSForm = ({ deviceList, formData, handleChange }) => {
}
export default function SendSMS() {
const { isOpen, onOpen, onClose } = useDisclosure()
const deviceList = useSelector(selectDeviceList)
const toast = useToast()
const dispatch = useAppDispatch()
@ -82,16 +72,16 @@ export default function SendSMS() {
const [formData, setFormData] = useState({
device: '',
receivers: '',
smsBody: '',
recipients: '',
message: '',
})
const handSend = (e) => {
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({
title: 'Please fill all fields',
status: 'error',
@ -99,7 +89,7 @@ export default function SendSMS() {
return
}
for (let receiver of receiversArray) {
for (let recipient of recipientsArray) {
// TODO: validate phone numbers
}
@ -107,8 +97,8 @@ export default function SendSMS() {
sendSMS({
deviceId,
payload: {
receivers: receiversArray,
smsBody,
recipients: recipientsArray,
message,
},
})
)
@ -123,39 +113,23 @@ export default function SendSMS() {
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 }}>
<SimpleGrid columns={{ base: 1, md: 2 }}>
<chakra.h1
textAlign={'center'}
fontSize={'4xl'}
// textAlign={'center'}
fontSize={'2xl'}
py={10}
fontWeight={'bold'}
>

9
web/components/dashboard/UserStatsCard.tsx

@ -10,20 +10,21 @@ export default function UserStatsCard({ ...props }) {
const { title, stat } = props
return (
<Stat
px={{ base: 4, md: 8 }}
py={'5'}
px={{ base: 2, md: 4 }}
py={'3'}
shadow={'xl'}
border={'1px solid'}
borderColor={useColorModeValue('gray.800', 'gray.500')}
rounded={'lg'}
style={{
height: '90px'
height: '90px',
}}
alignContent={'center'}
>
<StatLabel fontWeight={'medium'} isTruncated>
{title}
</StatLabel>
<StatNumber fontSize={'md'} fontWeight={'bold'}>
<StatNumber fontSize={'md'} fontWeight={'medium'}>
{stat}
</StatNumber>
</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 UserStats from '../components/dashboard/UserStats'
import GenerateApiKey from '../components/dashboard/GenerateApiKey'
@ -6,7 +15,7 @@ import DeviceList from '../components/dashboard/DeviceList'
import { useSelector } from 'react-redux'
import { selectAuthUser } from '../store/authSlice'
import Router from 'next/router'
import { useEffect } from 'react'
import { useEffect, useState } from 'react'
import SendSMS from '../components/dashboard/SendSMS'
import ErrorBoundary from '../components/ErrorBoundary'
import dynamic from 'next/dynamic'
@ -31,25 +40,64 @@ export default function Dashboard() {
Router.push('/login')
}
}, [authUser, toast])
return (
<>
<NoSSRAnimatedWrapper>
<UserStats />
<DashboardTabView />
</NoSSRAnimatedWrapper>
</>
)
}
const DashboardTabView = () => {
const [tabIndex, setTabIndex] = useState(1)
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 />
<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>
</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 {
receivers: string[]
smsBody: string
recipients: string[]
message: string
}
export interface ApiKeyEntity {

Loading…
Cancel
Save