Skip to content

Commit

Permalink
feat(upload&preview): complete reponsive for desktop
Browse files Browse the repository at this point in the history
  • Loading branch information
ngyngcphu committed Oct 28, 2023
1 parent 3365841 commit beb2357
Show file tree
Hide file tree
Showing 14 changed files with 258 additions and 179 deletions.
4 changes: 2 additions & 2 deletions src/components/home/Orders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Card, CardBody } from '@material-tailwind/react';
import { ArrowRightIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
import { MapPinIcon } from '@heroicons/react/24/solid';
import coin from '@assets/coin.png';
import { ORDER_STATUS } from '@constants';
import { ORDER_STATUS_COLOR } from '@constants';

export const Orders: Component<{ orders: OrderData[] }> = ({ orders }) => {
const sliderRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -36,7 +36,7 @@ export const Orders: Component<{ orders: OrderData[] }> = ({ orders }) => {
<CardBody className='p-2 lg:p-4'>
<div className='flex items-center justify-between font-semibold text-xs lg:text-base mb-2 lg:mb-4'>
<span>{order.id}</span>
<span className={`capitalize text-${ORDER_STATUS[order.status]}-500`}>
<span className={`capitalize text-${ORDER_STATUS_COLOR[order.status]}-500`}>
{order.status}
</span>
</div>
Expand Down
36 changes: 36 additions & 0 deletions src/components/order/common/FormFooter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { ReactNode } from 'react';
import coin from '@assets/coin.png';
import { useUserInfoStore } from '@states/home';

export const FormFooter: Component<{ children: ReactNode; totalCost: number }> = ({
children,
totalCost
}) => {
const { userInfoData } = useUserInfoStore();

return (
<div className='flex w-full h-16'>
<div className='flex justify-between items-center text-gray/4 w-[70%] px-4 py-2 bg-white'>
<div className='flex flex-col items-start'>
<p className='text-base font-medium'>Balance:</p>
<div className='grayscale flex items-center'>
<div className='w-6 h-6'>
<img src={coin} alt='Ballance Coin' />
</div>
<span>{userInfoData.coins}</span>
</div>
</div>
<div>
<p className='text-right text-base font-medium'>Total Cost</p>
<div className='flex items-center'>
<div className='w-7 h-7'>
<img src={coin} alt='Total Cost' />
</div>
<span className='text-2xl font-bold text-yellow/1'>{totalCost}</span>
</div>
</div>
</div>
{children}
</div>
);
};
1 change: 1 addition & 0 deletions src/components/order/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
* @file Automatically generated by barrelsby.
*/

export * from './FormFooter';
export * from './LayoutSide';
298 changes: 181 additions & 117 deletions src/components/order/desktop/UploadAndPreviewDocBox.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,54 @@
import { useState } from 'react';
import { useMemo, useState } from 'react';
import DocViewer, { DocViewerRenderers } from '@cyntler/react-doc-viewer';
import {
Button,
Dialog,
DialogBody,
DialogHeader,
IconButton,
Input,
Option,
Radio,
Select,
Typography
Select
} from '@material-tailwind/react';
import { ExclamationCircleIcon, MinusIcon, PlusIcon, TrashIcon } from '@heroicons/react/24/outline';
import { MinusIcon, PlusIcon, TrashIcon, XMarkIcon } from '@heroicons/react/24/outline';
import { ExclamationCircleIcon } from '@heroicons/react/24/solid';
import coinImage from '@assets/coin.png';
import { useLayoutSide, FormFooter } from '@components/order/common';
import { LAYOUT_SIDE, ORDER_STATUS } from '@constants';
import { useFileStore } from '@states/home';
import { useOrderPrintStore } from '@states/order';
import { formatFileSize } from '@utils';

export function useUploadAndPreviewDocBox() {
const { fileTarget } = useFileStore();
const [openDialog, setOpenDialog] = useState<boolean>(false);
const { fileTarget } = useFileStore();

const PreviewDocument = () =>
useMemo(() => {
if (fileTarget.url) {
return (
<DocViewer
config={{
header: {
disableFileName: true
},
pdfVerticalScrollByDefault: true
}}
pluginRenderers={DocViewerRenderers}
documents={[{ uri: fileTarget.url }]}
/>
);
} else return null;
}, []);

const UploadAndPreviewDocBox = () => {
const COINS_PER_DOC = 200;

const [numOfCopy, setNumOfCopy] = useState<number>(1);
const [selectedLayout, setSelectedLayout] = useState<string>(LAYOUT_SIDE.portrait);
const { openLayoutSide, LayoutSide } = useLayoutSide();
const { totalCost, setTotalCost, setOrderPrintList } = useOrderPrintStore();

const handleOpenDialog = () => setOpenDialog(!openDialog);
const handleDecrease = () => {
Expand All @@ -29,132 +59,166 @@ export function useUploadAndPreviewDocBox() {
const handleIncrease = () => {
setNumOfCopy(numOfCopy + 1);
};
const handleLayoutChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setSelectedLayout(e.target.value);
};
const handleSaveOrderPrintList = () => {
setOrderPrintList({
status: ORDER_STATUS.ready,
location: 'BK-B6',
fileName: fileTarget.name,
coins: COINS_PER_DOC * numOfCopy,
size: fileTarget.size,
number: numOfCopy,
pageNumber: 20,
paid: 'Not paid'
});
setTotalCost(totalCost + COINS_PER_DOC * numOfCopy);
};

return (
<Dialog size='xl' open={openDialog} handler={handleOpenDialog}>
<DialogBody className='grid grid-cols-3'>
<div className='flex flex-col'>
<div className='flex flex-col gap-4 p-4 border-b-2'>
<div>
<span className='text-gray/4 text-2xl font-bold'>Upload document</span>
<p className='flex items-center gap-2 font-medium text-xl'>
<span className='text-gray/4'>{fileTarget.name}</span>
<span className='text-gray/3'>{`(${formatFileSize(fileTarget.size)})`}</span>
</p>
<p className='flex items-center gap-1 text-lg'>
<img src={coinImage} className='grayscale w-6 h-6' />
<span className='text-gray/4 font-normal'>200 x {numOfCopy} copies = </span>
<img src={coinImage} className='w-6 h-6' />
<span className='text-yellow/1 font-bold'>{200 * numOfCopy}</span>
</p>
</div>
<div className='flex items-center justify-between'>
<div className='flex border-2'>
<span
className='p-0.5 border-r-2 flex items-center cursor-pointer'
onClick={handleDecrease}
>
<MinusIcon className='w-5 h-5' />
</span>
{numOfCopy > 0 && <span className='py-0.5 px-6'>{numOfCopy}</span>}
<span
className='p-0.5 border-l-2 flex items-center cursor-pointer'
onClick={handleIncrease}
>
<PlusIcon className='w-5 h-5' />
</span>
<DialogHeader className='justify-end p-0 bg-gray-200 rounded-t-md'>
<IconButton variant='text' onClick={() => setOpenDialog(false)} tabIndex={-1}>
<XMarkIcon className='w-6 h-6' />
</IconButton>
</DialogHeader>
<DialogBody className='grid grid-cols-3 gap-4 bg-gray-200 p-0'>
<div className='flex flex-col bg-white'>
<div className='h-[30rem] overflow-y-auto'>
<div className='flex flex-col gap-4 p-4 border-b-2'>
<div>
<span className='text-gray/4 text-xl font-bold'>Upload document</span>
<p className='flex items-center gap-2 font-medium text-lg'>
<span className='text-gray/4'>{fileTarget.name}</span>
<span className='text-gray/3'>{`(${formatFileSize(fileTarget.size)})`}</span>
</p>
<p className='flex items-center gap-1 text-base'>
<img src={coinImage} className='grayscale w-6 h-6' />
<span className='text-gray/4 font-normal'>
{COINS_PER_DOC} x {numOfCopy} copies ={' '}
</span>
<img src={coinImage} className='w-6 h-6' />
<span className='text-yellow/1 font-bold'>{COINS_PER_DOC * numOfCopy}</span>
</p>
</div>
<TrashIcon className='w-7 h-7' />
</div>
</div>
<div className='p-6 text-gray/4 bg-white mt-4'>
<div className='mb-8'>
<Typography className='font-bold'>Layout</Typography>
<div className='flex flex-col -ml-3'>
{/* <Radio
name='layout'
label='Portrait'
value='Portrait'
onChange={handleLayoutChange}
checked={selectedLayout === 'Portrait'}
crossOrigin=''
defaultChecked
/>
<Radio
name='layout'
label='Landscape'
value='Landscape'
crossOrigin=''
onChange={handleLayoutChange}
checked={selectedLayout === 'Landscape'}
/> */}
<div className='flex items-center justify-between'>
<div className='flex border-2'>
<span
className='p-0.5 border-r-2 flex items-center cursor-pointer'
onClick={handleDecrease}
>
<MinusIcon className='w-5 h-5' />
</span>
{numOfCopy > 0 && <span className='py-0.5 px-6'>{numOfCopy}</span>}
<span
className='p-0.5 border-l-2 flex items-center cursor-pointer'
onClick={handleIncrease}
>
<PlusIcon className='w-5 h-5' />
</span>
</div>
<TrashIcon className='w-7 h-7' />
</div>
</div>
<div className='mb-8'>
<Typography className='font-bold'>Pages</Typography>
<div className='flex flex-col -ml-3'>
<Radio name='pages' label='All' crossOrigin='' defaultChecked />
<Radio name='pages' label='Odd pages only' crossOrigin='' />
<Radio name='pages' label='Even pages only' crossOrigin='' />
<Radio
name='pages'
label={<Input label='Specific Pages' crossOrigin='' />}
crossOrigin=''
/>
<div className='flex flex-col gap-4 p-4 text-gray/4 bg-white'>
<div>
<span className='text-xl font-bold'>Layout</span>
<div className='flex flex-col -ml-3'>
<Radio
name='layout'
label={LAYOUT_SIDE.portrait}
value={LAYOUT_SIDE.portrait}
onChange={handleLayoutChange}
checked={selectedLayout === LAYOUT_SIDE.portrait}
crossOrigin=''
tabIndex={-1}
/>
<Radio
name='layout'
label={LAYOUT_SIDE.landscape}
value={LAYOUT_SIDE.landscape}
onChange={handleLayoutChange}
checked={selectedLayout === LAYOUT_SIDE.landscape}
crossOrigin=''
tabIndex={-1}
/>
</div>
</div>
</div>
<div className='mb-8'>
<Typography className='font-bold mb-4'>Pages per sheet</Typography>
<Select label='Select an option'>
{['1', '2', '4', '8', '16'].map((item) => {
return (
<Option key={item} value={item}>
{item}
</Option>
);
})}
</Select>
</div>
<div>
<Typography className='font-bold'>Page Side</Typography>
<div className='-ml-3'>
<Radio name='side' label='One side' crossOrigin='' />
<div className='flex'>
{/* <Radio
name='side'
<div>
<span className='text-xl font-bold'>Pages</span>
<div className='flex flex-col -ml-3'>
<Radio name='pages' label='All' crossOrigin='' tabIndex={-1} defaultChecked />
<Radio name='pages' label='Odd pages only' tabIndex={-1} crossOrigin='' />
<Radio name='pages' label='Even pages only' tabIndex={-1} crossOrigin='' />
<Radio
name='pages'
label={<Input label='Specific Pages' crossOrigin='' />}
crossOrigin=''
defaultChecked
label={
selectedLayout === 'Portrait' ? (
<Select label='Both sides'>
<Option>Long edge (Left)</Option>
<Option>Long edge (Right)</Option>
<Option>Short edge (Top)</Option>
<Option>Short edge (Bottom)</Option>
</Select>
) : (
<Select label='Both sides'>
<Option>Short edge (Left)</Option>
<Option>Short edge (Right)</Option>
<Option>Long edge (Top)</Option>
<Option>Long edge (Bottom)</Option>
</Select>
)
}
/> */}
''
<ExclamationCircleIcon
width={24}
className='ml-6 cursor-pointer text-gray-300 hover:text-black'
// onClick={handleOpen}
/>
{/* <DialogForm layout={selectedLayout} open={open} handleOpen={handleOpen} /> */}
</div>
</div>
<div>
<span className='text-xl font-bold mb-4'>Pages per sheet</span>
<Select label='Select an option'>
{['1', '2', '4', '8', '16'].map((item) => {
return (
<Option key={item} value={item}>
{item}
</Option>
);
})}
</Select>
</div>
<div>
<span className='font-bold text-xl'>Page Side</span>
<div className='-ml-3'>
<Radio name='side' label='One side' crossOrigin='' />
<div className='flex items-center gap-4'>
<Radio
name='side'
crossOrigin=''
defaultChecked
label={
selectedLayout === LAYOUT_SIDE.portrait ? (
<Select label='Both sides'>
<Option>Long edge (Left)</Option>
<Option>Long edge (Right)</Option>
<Option>Short edge (Top)</Option>
<Option>Short edge (Bottom)</Option>
</Select>
) : (
<Select label='Both sides'>
<Option>Short edge (Left)</Option>
<Option>Short edge (Right)</Option>
<Option>Long edge (Top)</Option>
<Option>Long edge (Bottom)</Option>
</Select>
)
}
/>
<ExclamationCircleIcon
className='w-6 h-6 cursor-pointer text-gray-500 hover:text-black'
onClick={openLayoutSide}
/>
<LayoutSide layout={selectedLayout} />
</div>
</div>
</div>
</div>
</div>
<FormFooter totalCost={totalCost + COINS_PER_DOC * numOfCopy}>
<Button
color={fileTarget.size > 0 ? 'blue' : 'gray'}
className='rounded-none w-[30%]'
onClick={handleSaveOrderPrintList}
disabled={fileTarget.size === 0}
>
<span className='text-base'>Save</span>
</Button>
</FormFooter>
</div>
<div>B</div>
<div className='h-[34rem] overflow-y-auto col-span-2'>{<PreviewDocument />}</div>
</DialogBody>
</Dialog>
);
Expand Down
Loading

0 comments on commit beb2357

Please sign in to comment.