UI Updated
This commit is contained in:
parent
f79ae65f27
commit
ad0a06d593
@ -7,7 +7,7 @@ import navbar from './navbar'
|
||||
import layout from './layout'
|
||||
import todo from '@src/views/apps/todo/store/reducer'
|
||||
import users from '@src/views/apps/user/store/reducer'
|
||||
import dataTables from '@src/views/tables/data-tables/store/reducer'
|
||||
|
||||
import account from '../../views/apps/company/store/reducer'
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
@ -16,7 +16,6 @@ const rootReducer = combineReducers({
|
||||
users,
|
||||
navbar,
|
||||
layout,
|
||||
dataTables,
|
||||
account
|
||||
})
|
||||
|
||||
|
@ -4,12 +4,8 @@ import Avatar from '@components/avatar'
|
||||
import Timeline from './timeline'
|
||||
import AvatarGroup from '@components/avatar-group'
|
||||
import jsonImg from '@src/assets/images/icons/json.png'
|
||||
import InvoiceList from '@src/views/apps/invoice/list'
|
||||
import ceo from '@src/assets/images/portrait/small/avatar-s-9.jpg'
|
||||
import { ThemeColors } from '@src/utility/context/ThemeColors'
|
||||
import Sales from '@src/views/ui-elements/cards/analytics/Sales'
|
||||
import AvgSessions from '@src/views/ui-elements/cards/analytics/AvgSessions'
|
||||
import CardAppDesign from '@src/views/ui-elements/cards/advance/CardAppDesign'
|
||||
import Contacts from './Contacts'
|
||||
import Tasks from './Tasks'
|
||||
import Notes from './Notes'
|
||||
@ -17,7 +13,6 @@ import TaskSidebar from './TaskSidebar'
|
||||
import ContactSidebar from './ContactSidebar'
|
||||
import ActivitySidebar from '../activityTree/ActivitySidebar'
|
||||
import ActivityTree from '../activityTree/ActivityTree'
|
||||
import SupportTracker from '@src/views/ui-elements/cards/analytics/SupportTracker'
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
@ -26,8 +21,6 @@ import {
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
CardBody,
|
||||
InputGroup,
|
||||
CustomInput,
|
||||
DropdownMenu,
|
||||
DropdownItem,
|
||||
InputGroupText,
|
||||
@ -36,9 +29,6 @@ import {
|
||||
UncontrolledDropdown
|
||||
} from 'reactstrap'
|
||||
import { List, Menu, Search, MoreVertical } from 'react-feather'
|
||||
import OrdersReceived from '@src/views/ui-elements/cards/statistics/OrdersReceived'
|
||||
import CardCongratulations from '@src/views/ui-elements/cards/advance/CardCongratulations'
|
||||
import SubscribersGained from '@src/views/ui-elements/cards/statistics/SubscribersGained'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
|
||||
import '@styles/react/libs/charts/apex-charts.scss'
|
||||
|
@ -13,7 +13,6 @@ import { Row, Col, Alert } from 'reactstrap'
|
||||
import PlanCard from './PlanCard'
|
||||
import UserInfoCard from './UserInfoCard'
|
||||
import UserTimeline from './UserTimeline'
|
||||
import InvoiceList from '../../invoice/list'
|
||||
import PermissionsTable from './PermissionsTable'
|
||||
|
||||
// ** Styles
|
||||
@ -48,11 +47,6 @@ const UserView = props => {
|
||||
<PermissionsTable />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col sm='12'>
|
||||
<InvoiceList />
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
) : (
|
||||
<Alert color='danger'>
|
||||
|
@ -1,60 +0,0 @@
|
||||
// ** React Imports
|
||||
import { Fragment } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
// ** Third Party Components
|
||||
import { Card, CardBody, Button, Input, CustomInput, Label } from 'reactstrap'
|
||||
|
||||
const AddActions = () => {
|
||||
return (
|
||||
<Fragment>
|
||||
<Card className='invoice-action-wrapper'>
|
||||
<CardBody>
|
||||
<Button.Ripple color='primary' block className='mb-75' disabled>
|
||||
Send Invoice
|
||||
</Button.Ripple>
|
||||
<Button.Ripple tag={Link} to='/apps/invoice/preview' color='primary' block outline className='mb-75'>
|
||||
Preview
|
||||
</Button.Ripple>
|
||||
<Button.Ripple color='primary' block outline>
|
||||
Save
|
||||
</Button.Ripple>
|
||||
</CardBody>
|
||||
</Card>
|
||||
<div className='mt-2'>
|
||||
<div className='invoice-payment-option'>
|
||||
<p className='mb-50'>Accept payments via</p>
|
||||
<Input type='select' id='payment-select'>
|
||||
<option>Debit Card</option>
|
||||
<option>Credit Card</option>
|
||||
<option>Paypal</option>
|
||||
<option>Internet Banking</option>
|
||||
<option>UPI Transfer</option>
|
||||
</Input>
|
||||
</div>
|
||||
<div className='invoice-terms mt-1'>
|
||||
<div className='d-flex justify-content-between'>
|
||||
<Label className='mb-0' for='payment-terms'>
|
||||
Payment Terms
|
||||
</Label>
|
||||
<CustomInput type='switch' id='payment-terms' defaultChecked />
|
||||
</div>
|
||||
<div className='d-flex justify-content-between py-1'>
|
||||
<Label className='mb-0' for='client-notes'>
|
||||
Client Notes
|
||||
</Label>
|
||||
<CustomInput type='switch' id='client-notes' defaultChecked />
|
||||
</div>
|
||||
<div className='d-flex justify-content-between'>
|
||||
<Label className='mb-0' for='payment-stub'>
|
||||
Payment Stub
|
||||
</Label>
|
||||
<CustomInput type='switch' id='payment-stub' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddActions
|
@ -1,477 +0,0 @@
|
||||
// ** React Imports
|
||||
import { Fragment, useState, useEffect } from 'react'
|
||||
|
||||
// ** Custom Components
|
||||
import Sidebar from '@components/sidebar'
|
||||
import Repeater from '@components/repeater'
|
||||
|
||||
// ** Third Party Components
|
||||
import axios from 'axios'
|
||||
import Flatpickr from 'react-flatpickr'
|
||||
import { SlideDown } from 'react-slidedown'
|
||||
import { X, Plus, Hash } from 'react-feather'
|
||||
import Select, { components } from 'react-select'
|
||||
import { selectThemeColors } from '@utils'
|
||||
import {
|
||||
Card,
|
||||
CardBody,
|
||||
CardText,
|
||||
Row,
|
||||
Col,
|
||||
Form,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupText,
|
||||
FormGroup,
|
||||
Label,
|
||||
Button,
|
||||
UncontrolledTooltip
|
||||
} from 'reactstrap'
|
||||
|
||||
// ** Styles
|
||||
import 'react-slidedown/lib/slidedown.css'
|
||||
import '@styles/react/libs/react-select/_react-select.scss'
|
||||
import '@styles/react/libs/flatpickr/flatpickr.scss'
|
||||
import '@styles/base/pages/app-invoice.scss'
|
||||
|
||||
const AddCard = () => {
|
||||
// ** States
|
||||
const [count, setCount] = useState(1)
|
||||
const [value, setValue] = useState({})
|
||||
const [open, setOpen] = useState(false)
|
||||
const [clients, setClients] = useState(null)
|
||||
const [selected, setSelected] = useState(null)
|
||||
const [picker, setPicker] = useState(new Date())
|
||||
const [invoiceNumber, setInvoiceNumber] = useState(false)
|
||||
const [dueDatepicker, setDueDatePicker] = useState(new Date())
|
||||
const [options, setOptions] = useState([
|
||||
{
|
||||
value: 'add-new',
|
||||
label: 'Add New Customer',
|
||||
type: 'button',
|
||||
color: 'flat-success'
|
||||
}
|
||||
])
|
||||
|
||||
useEffect(() => {
|
||||
// ** Get Clients
|
||||
axios.get('/api/invoice/clients').then(response => {
|
||||
const arr = options
|
||||
response.data.map(item => arr.push({ value: item.name, label: item.name }))
|
||||
setOptions([...arr])
|
||||
setClients(response.data)
|
||||
})
|
||||
|
||||
// ** Get Invoices & Set Invoice Number
|
||||
axios
|
||||
.get('/apps/invoice/invoices', {
|
||||
page: 1,
|
||||
perPage: 10,
|
||||
status: '',
|
||||
q: ''
|
||||
})
|
||||
.then(response => {
|
||||
const lastInvoiceNumber = Math.max.apply(
|
||||
Math,
|
||||
response.data.allData.map(i => i.id)
|
||||
)
|
||||
setInvoiceNumber(lastInvoiceNumber + 1)
|
||||
})
|
||||
}, [])
|
||||
|
||||
// ** Deletes form
|
||||
const deleteForm = e => {
|
||||
e.preventDefault()
|
||||
e.target.closest('.repeater-wrapper').remove()
|
||||
}
|
||||
|
||||
// ** Function to toggle sidebar
|
||||
const toggleSidebar = () => setOpen(!open)
|
||||
|
||||
// ** Vars
|
||||
const countryOptions = [
|
||||
{ value: 'australia', label: 'Australia' },
|
||||
{ value: 'canada', label: 'Canada' },
|
||||
{ value: 'russia', label: 'Russia' },
|
||||
{ value: 'saudi-arabia', label: 'Saudi Arabia' },
|
||||
{ value: 'singapore', label: 'Singapore' },
|
||||
{ value: 'sweden', label: 'Sweden' },
|
||||
{ value: 'switzerland', label: 'Switzerland' },
|
||||
{ value: 'united-kingdom', label: 'United Kingdom' },
|
||||
{ value: 'united-arab-emirates', label: 'United Arab Emirates' },
|
||||
{ value: 'united-states-of-america', label: 'United States of America' }
|
||||
]
|
||||
|
||||
// ** Custom Options Component
|
||||
const OptionComponent = ({ data, ...props }) => {
|
||||
if (data.type === 'button') {
|
||||
return (
|
||||
<Button className='text-left rounded-0' color={data.color} block onClick={() => setOpen(true)}>
|
||||
<Plus size={14} /> <span className='align-middle ml-50'>{data.label}</span>
|
||||
</Button>
|
||||
)
|
||||
} else {
|
||||
return <components.Option {...props}> {data.label} </components.Option>
|
||||
}
|
||||
}
|
||||
|
||||
// ** Invoice To OnChange
|
||||
const handleInvoiceToChange = data => {
|
||||
setValue(data)
|
||||
setSelected(clients.filter(i => i.name === data.value)[0])
|
||||
}
|
||||
|
||||
const note =
|
||||
'It was a pleasure working with you and your team. We hope you will keep us in mind for future freelance projects. Thank You!'
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Card className='invoice-preview-card mb-0'>
|
||||
{/* Header */}
|
||||
<CardBody className='invoice-padding pb-0'>
|
||||
<div className='d-flex justify-content-between flex-md-row flex-column invoice-spacing mt-0'>
|
||||
<div>
|
||||
<div className='logo-wrapper'>
|
||||
<svg viewBox='0 0 139 95' version='1.1' height='24'>
|
||||
<defs>
|
||||
<linearGradient id='invoice-linearGradient-1' x1='100%' y1='10.5120544%' x2='50%' y2='89.4879456%'>
|
||||
<stop stopColor='#000000' offset='0%'></stop>
|
||||
<stop stopColor='#FFFFFF' offset='100%'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id='invoice-linearGradient-2'
|
||||
x1='64.0437835%'
|
||||
y1='46.3276743%'
|
||||
x2='37.373316%'
|
||||
y2='100%'
|
||||
>
|
||||
<stop stopColor='#EEEEEE' stopOpacity='0' offset='0%'></stop>
|
||||
<stop stopColor='#FFFFFF' offset='100%'></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g stroke='none' strokeWidth='1' fill='none' fillRule='evenodd'>
|
||||
<g transform='translate(-400.000000, -178.000000)'>
|
||||
<g transform='translate(400.000000, 178.000000)'>
|
||||
<path
|
||||
className='text-primary'
|
||||
d='M-5.68434189e-14,2.84217094e-14 L39.1816085,2.84217094e-14 L69.3453773,32.2519224 L101.428699,2.84217094e-14 L138.784583,2.84217094e-14 L138.784199,29.8015838 C137.958931,37.3510206 135.784352,42.5567762 132.260463,45.4188507 C128.736573,48.2809251 112.33867,64.5239941 83.0667527,94.1480575 L56.2750821,94.1480575 L6.71554594,44.4188507 C2.46876683,39.9813776 0.345377275,35.1089553 0.345377275,29.8015838 C0.345377275,24.4942122 0.230251516,14.560351 -5.68434189e-14,2.84217094e-14 Z'
|
||||
style={{ fill: 'currentColor' }}
|
||||
></path>
|
||||
<path
|
||||
d='M69.3453773,32.2519224 L101.428699,1.42108547e-14 L138.784583,1.42108547e-14 L138.784199,29.8015838 C137.958931,37.3510206 135.784352,42.5567762 132.260463,45.4188507 C128.736573,48.2809251 112.33867,64.5239941 83.0667527,94.1480575 L56.2750821,94.1480575 L32.8435758,70.5039241 L69.3453773,32.2519224 Z'
|
||||
fill='url(#invoice-linearGradient-1)'
|
||||
opacity='0.2'
|
||||
></path>
|
||||
<polygon
|
||||
fill='#000000'
|
||||
opacity='0.049999997'
|
||||
points='69.3922914 32.4202615 32.8435758 70.5039241 54.0490008 16.1851325'
|
||||
></polygon>
|
||||
<polygon
|
||||
fill='#000000'
|
||||
opacity='0.099999994'
|
||||
points='69.3922914 32.4202615 32.8435758 70.5039241 58.3683556 20.7402338'
|
||||
></polygon>
|
||||
<polygon
|
||||
fill='url(#invoice-linearGradient-2)'
|
||||
opacity='0.099999994'
|
||||
points='101.428699 0 83.0667527 94.1480575 130.378721 47.0740288'
|
||||
></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<h3 className='text-primary invoice-logo'></h3>
|
||||
</div>
|
||||
<p className='card-text mb-25'>Office 149, 450 South Brand Brooklyn</p>
|
||||
<p className='card-text mb-25'>San Diego County, CA 91905, USA</p>
|
||||
<p className='card-text mb-0'>+1 (123) 456 7891, +44 (876) 543 2198</p>
|
||||
</div>
|
||||
<div className='invoice-number-date mt-md-0 mt-2'>
|
||||
<div className='d-flex align-items-center justify-content-md-end mb-1'>
|
||||
<h4 className='invoice-title'>Invoice</h4>
|
||||
<InputGroup className='input-group-merge invoice-edit-input-group disabled'>
|
||||
<InputGroupAddon addonType='prepend'>
|
||||
<InputGroupText>
|
||||
<Hash size={15} />
|
||||
</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<Input
|
||||
type='number'
|
||||
className='invoice-edit-input'
|
||||
value={invoiceNumber || 3171}
|
||||
placeholder='53634'
|
||||
disabled
|
||||
/>
|
||||
</InputGroup>
|
||||
</div>
|
||||
<div className='d-flex align-items-center mb-1'>
|
||||
<span className='title'>Date:</span>
|
||||
<Flatpickr
|
||||
value={picker}
|
||||
onChange={date => setPicker(date)}
|
||||
className='form-control invoice-edit-input date-picker'
|
||||
/>
|
||||
</div>
|
||||
<div className='d-flex align-items-center'>
|
||||
<span className='title'>Due Date:</span>
|
||||
<Flatpickr
|
||||
value={dueDatepicker}
|
||||
onChange={date => setDueDatePicker(date)}
|
||||
className='form-control invoice-edit-input due-date-picker'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardBody>
|
||||
{/* /Header */}
|
||||
|
||||
<hr className='invoice-spacing' />
|
||||
|
||||
{/* Address and Contact */}
|
||||
<CardBody className='invoice-padding pt-0'>
|
||||
<Row className='row-bill-to invoice-spacing'>
|
||||
<Col className='col-bill-to pl-0' lg='8'>
|
||||
<h6 className='invoice-to-title'>Invoice To:</h6>
|
||||
<div className='invoice-customer'>
|
||||
{clients !== null ? (
|
||||
<Fragment>
|
||||
<Select
|
||||
className='react-select'
|
||||
classNamePrefix='select'
|
||||
id='label'
|
||||
value={value}
|
||||
options={options}
|
||||
theme={selectThemeColors}
|
||||
components={{
|
||||
Option: OptionComponent
|
||||
}}
|
||||
onChange={handleInvoiceToChange}
|
||||
/>
|
||||
{selected !== null ? (
|
||||
<div className='customer-details mt-1'>
|
||||
<p className='mb-25'>{selected.name}</p>
|
||||
<p className='mb-25'>{selected.company}</p>
|
||||
<p className='mb-25'>{selected.address}</p>
|
||||
<p className='mb-25'>{selected.country}</p>
|
||||
<p className='mb-0'>{selected.contact}</p>
|
||||
<p className='mb-0'>{selected.companyEmail}</p>
|
||||
</div>
|
||||
) : null}
|
||||
</Fragment>
|
||||
) : null}
|
||||
</div>
|
||||
</Col>
|
||||
<Col className='pr-0 mt-xl-0 mt-2' lg='4'>
|
||||
<h6 className='mb-2'>Payment Details:</h6>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className='pr-1'>Total Due:</td>
|
||||
<td>
|
||||
<span className='font-weight-bolder'>$12,110.55</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>Bank name:</td>
|
||||
<td>American Bank</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>Country:</td>
|
||||
<td>United States</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>IBAN:</td>
|
||||
<td>ETD95476213874685</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>SWIFT code:</td>
|
||||
<td>BR91905</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
{/* /Address and Contact */}
|
||||
|
||||
{/* Product Details */}
|
||||
<CardBody className='invoice-padding invoice-product-details'>
|
||||
<Repeater count={count}>
|
||||
{i => {
|
||||
const Tag = i === 0 ? 'div' : SlideDown
|
||||
return (
|
||||
<Tag key={i} className='repeater-wrapper'>
|
||||
<Row>
|
||||
<Col className='d-flex product-details-border position-relative pr-0' sm='12'>
|
||||
<Row className='w-100 pr-lg-0 pr-1 py-2'>
|
||||
<Col className='mb-lg-0 mb-2 mt-lg-0 mt-2' lg='5' sm='12'>
|
||||
<CardText className='col-title mb-md-50 mb-0'>Item</CardText>
|
||||
<Input type='select' className='item-details'>
|
||||
<option>App Design</option>
|
||||
<option>App Customization</option>
|
||||
<option>ABC Template</option>
|
||||
<option>App Development</option>
|
||||
</Input>
|
||||
<Input className='mt-2' type='textarea' rows='1' defaultValue='Customization & Bug Fixes' />
|
||||
</Col>
|
||||
<Col className='my-lg-0 my-2' lg='3' sm='12'>
|
||||
<CardText className='col-title mb-md-2 mb-0'>Cost</CardText>
|
||||
<Input type='number' defaultValue='24' placeholder='24' />
|
||||
<div className='mt-2'>
|
||||
<span>Discount:</span> <span>0%</span>
|
||||
<span id={`tax1-${i}`} className='ml-50'>
|
||||
0%
|
||||
</span>
|
||||
<span id={`tax2-${i}`} className='ml-50'>
|
||||
0%
|
||||
</span>
|
||||
<UncontrolledTooltip target={`tax1-${i}`}>Tax 1</UncontrolledTooltip>
|
||||
<UncontrolledTooltip target={`tax2-${i}`}>Tax 2</UncontrolledTooltip>
|
||||
</div>
|
||||
</Col>
|
||||
<Col className='my-lg-0 my-2' lg='2' sm='12'>
|
||||
<CardText className='col-title mb-md-2 mb-0'>Qty</CardText>
|
||||
<Input type='number' defaultValue='1' placeholder='1' />
|
||||
</Col>
|
||||
<Col className='my-lg-0 mt-2' lg='2' sm='12'>
|
||||
<CardText className='col-title mb-md-50 mb-0'>Price</CardText>
|
||||
<CardText className='mb-0'>$24.00</CardText>
|
||||
</Col>
|
||||
</Row>
|
||||
<div className='d-flex flex-column align-items-center justify-content-start border-left invoice-product-actions py-50 px-25'>
|
||||
<X size={18} className='cursor-pointer' onClick={deleteForm} />
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Tag>
|
||||
)
|
||||
}}
|
||||
</Repeater>
|
||||
<Row className='mt-1'>
|
||||
<Col sm='12' className='px-0'>
|
||||
<Button.Ripple color='primary' size='sm' className='btn-add-new' onClick={() => setCount(count + 1)}>
|
||||
<Plus size={14} className='mr-25'></Plus>
|
||||
<span className='align-middle'>Add Item</span>
|
||||
</Button.Ripple>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
|
||||
{/* /Product Details */}
|
||||
|
||||
{/* Invoice Total */}
|
||||
<CardBody className='invoice-padding'>
|
||||
<Row className='invoice-sales-total-wrapper'>
|
||||
<Col className='mt-md-0 mt-3' md={{ size: '6', order: 1 }} xs={{ size: 12, order: 2 }}>
|
||||
<div className='d-flex align-items-center mb-1'>
|
||||
<Label for='salesperson' className='form-label'>
|
||||
Salesperson:
|
||||
</Label>
|
||||
<Input type='text' className='ml-50' id='salesperson' placeholder='Edward Crowley' />
|
||||
</div>
|
||||
</Col>
|
||||
<Col className='d-flex justify-content-end' md={{ size: '6', order: 2 }} xs={{ size: 12, order: 1 }}>
|
||||
<div className='invoice-total-wrapper'>
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Subtotal:</p>
|
||||
<p className='invoice-total-amount'>$1800</p>
|
||||
</div>
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Discount:</p>
|
||||
<p className='invoice-total-amount'>$28</p>
|
||||
</div>
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Tax:</p>
|
||||
<p className='invoice-total-amount'>21%</p>
|
||||
</div>
|
||||
<hr className='my-50' />
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Total:</p>
|
||||
<p className='invoice-total-amount'>$1690</p>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
{/* /Invoice Total */}
|
||||
|
||||
<hr className='invoice-spacing mt-0' />
|
||||
|
||||
{/* Invoice Note */}
|
||||
<CardBody className='invoice-padding py-0'>
|
||||
<Row>
|
||||
<Col>
|
||||
<FormGroup className='mb-2'>
|
||||
<Label for='note' className='form-label font-weight-bold'>
|
||||
Note:
|
||||
</Label>
|
||||
<Input type='textarea' rows='2' id='note' defaultValue={note} />
|
||||
</FormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
{/* /Invoice Note */}
|
||||
</Card>
|
||||
|
||||
<Sidebar
|
||||
size='lg'
|
||||
open={open}
|
||||
title='Add Payment'
|
||||
headerClassName='mb-1'
|
||||
contentClassName='p-0'
|
||||
toggleSidebar={toggleSidebar}
|
||||
>
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<Label for='customer-name' className='form-label'>
|
||||
Customer Name
|
||||
</Label>
|
||||
<Input id='customer-name' placeholder='John Doe' />
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='customer-email' className='form-label'>
|
||||
Customer Email
|
||||
</Label>
|
||||
<Input type='email' id='customer-email' placeholder='example@domain.com' />
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='customer-address' className='form-label'>
|
||||
Customer Address
|
||||
</Label>
|
||||
<Input type='textarea' cols='2' rows='2' id='customer-address' placeholder='1307 Lady Bug Drive New York' />
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='country' className='form-label'>
|
||||
Country
|
||||
</Label>
|
||||
<Select
|
||||
theme={selectThemeColors}
|
||||
className='react-select'
|
||||
classNamePrefix='select'
|
||||
options={countryOptions}
|
||||
isClearable={false}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='customer-contact' className='form-label'>
|
||||
Contact
|
||||
</Label>
|
||||
<Input type='number' id='customer-contact' placeholder='763-242-9206' />
|
||||
</FormGroup>
|
||||
<FormGroup className='d-flex flex-wrap mt-2'>
|
||||
<Button className='mr-1' color='primary' onClick={() => setOpen(false)}>
|
||||
Add
|
||||
</Button>
|
||||
<Button color='secondary' onClick={() => setOpen(false)} outline>
|
||||
Cancel
|
||||
</Button>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
</Sidebar>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddCard
|
@ -1,27 +0,0 @@
|
||||
// ** Invoice Add Components
|
||||
import AddCard from './AddCard'
|
||||
import AddActions from './AddActions'
|
||||
|
||||
// ** Third Party Components
|
||||
import { Row, Col } from 'reactstrap'
|
||||
|
||||
// ** Styles
|
||||
import '@styles/react/libs/flatpickr/flatpickr.scss'
|
||||
import '@styles/base/pages/app-invoice.scss'
|
||||
|
||||
const InvoiceAdd = () => {
|
||||
return (
|
||||
<div className='invoice-add-wrapper'>
|
||||
<Row className='invoice-add'>
|
||||
<Col xl={9} md={8} sm={12}>
|
||||
<AddCard />
|
||||
</Col>
|
||||
<Col xl={3} md={4} sm={12}>
|
||||
<AddActions />
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default InvoiceAdd
|
@ -1,63 +0,0 @@
|
||||
// ** React Imports
|
||||
import { Fragment } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
// ** Third Party Components
|
||||
import { Card, CardBody, Button, Input, CustomInput, Label } from 'reactstrap'
|
||||
|
||||
const EditActions = ({ setSendSidebarOpen, setAddPaymentOpen }) => {
|
||||
return (
|
||||
<Fragment>
|
||||
<Card className='invoice-action-wrapper'>
|
||||
<CardBody>
|
||||
<Button.Ripple color='primary' block className='mb-75' onClick={() => setSendSidebarOpen(true)}>
|
||||
Send Invoice
|
||||
</Button.Ripple>
|
||||
<Button.Ripple tag={Link} to='/apps/invoice/preview' color='primary' block outline className='mb-75'>
|
||||
Preview
|
||||
</Button.Ripple>
|
||||
<Button.Ripple color='primary' block outline className='mb-75'>
|
||||
Save
|
||||
</Button.Ripple>
|
||||
<Button.Ripple color='success' block onClick={() => setAddPaymentOpen(true)}>
|
||||
Add Payment
|
||||
</Button.Ripple>
|
||||
</CardBody>
|
||||
</Card>
|
||||
<div className='mt-2'>
|
||||
<div className='invoice-payment-option'>
|
||||
<p className='mb-50'>Accept payments via</p>
|
||||
<Input type='select' id='payment-select'>
|
||||
<option>Debit Card</option>
|
||||
<option>Credit Card</option>
|
||||
<option>Paypal</option>
|
||||
<option>Internet Banking</option>
|
||||
<option>UPI Transfer</option>
|
||||
</Input>
|
||||
</div>
|
||||
<div className='invoice-terms mt-1'>
|
||||
<div className='d-flex justify-content-between'>
|
||||
<Label className='mb-0' for='payment-terms'>
|
||||
Payment Terms
|
||||
</Label>
|
||||
<CustomInput type='switch' id='payment-terms' defaultChecked />
|
||||
</div>
|
||||
<div className='d-flex justify-content-between py-1'>
|
||||
<Label className='mb-0' for='client-notes'>
|
||||
Client Notes
|
||||
</Label>
|
||||
<CustomInput type='switch' id='client-notes' defaultChecked />
|
||||
</div>
|
||||
<div className='d-flex justify-content-between'>
|
||||
<Label className='mb-0' for='payment-stub'>
|
||||
Payment Stub
|
||||
</Label>
|
||||
<CustomInput type='switch' id='payment-stub' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default EditActions
|
@ -1,313 +0,0 @@
|
||||
// ** React Imports
|
||||
import { useState } from 'react'
|
||||
|
||||
// ** Third Party Components
|
||||
import {
|
||||
Card,
|
||||
CardBody,
|
||||
CardText,
|
||||
Row,
|
||||
Col,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupText,
|
||||
UncontrolledTooltip,
|
||||
FormGroup,
|
||||
Label,
|
||||
Button
|
||||
} from 'reactstrap'
|
||||
import Flatpickr from 'react-flatpickr'
|
||||
import Repeater from '@components/repeater'
|
||||
import { SlideDown } from 'react-slidedown'
|
||||
import { X, Plus, Hash } from 'react-feather'
|
||||
|
||||
// ** Styles
|
||||
import 'react-slidedown/lib/slidedown.css'
|
||||
import '@styles/react/libs/flatpickr/flatpickr.scss'
|
||||
import '@styles/base/pages/app-invoice.scss'
|
||||
|
||||
const InvoiceEditCard = ({ data }) => {
|
||||
// ** States
|
||||
const [count, setCount] = useState(1)
|
||||
const [picker, setPicker] = useState(new Date(data.invoice.issuedDate))
|
||||
const [dueDatepicker, setDueDatePicker] = useState(new Date(data.invoice.dueDate))
|
||||
|
||||
// ** Deletes form
|
||||
const deleteForm = e => {
|
||||
e.preventDefault()
|
||||
e.target.closest('.repeater-wrapper').remove()
|
||||
}
|
||||
|
||||
const note =
|
||||
'It was a pleasure working with you and your team. We hope you will keep us in mind for future freelance projects. Thank You!'
|
||||
|
||||
return (
|
||||
<Card className='invoice-preview-card mb-0'>
|
||||
{/* Header */}
|
||||
<CardBody className='invoice-padding pb-0'>
|
||||
<div className='d-flex justify-content-between flex-md-row flex-column invoice-spacing mt-0'>
|
||||
<div>
|
||||
<div className='logo-wrapper'>
|
||||
<svg viewBox='0 0 139 95' version='1.1' height='24'>
|
||||
<defs>
|
||||
<linearGradient id='invoice-linearGradient-1' x1='100%' y1='10.5120544%' x2='50%' y2='89.4879456%'>
|
||||
<stop stopColor='#000000' offset='0%'></stop>
|
||||
<stop stopColor='#FFFFFF' offset='100%'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id='invoice-linearGradient-2'
|
||||
x1='64.0437835%'
|
||||
y1='46.3276743%'
|
||||
x2='37.373316%'
|
||||
y2='100%'
|
||||
>
|
||||
<stop stopColor='#EEEEEE' stopOpacity='0' offset='0%'></stop>
|
||||
<stop stopColor='#FFFFFF' offset='100%'></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g stroke='none' strokeWidth='1' fill='none' fillRule='evenodd'>
|
||||
<g transform='translate(-400.000000, -178.000000)'>
|
||||
<g transform='translate(400.000000, 178.000000)'>
|
||||
<path
|
||||
className='text-primary'
|
||||
d='M-5.68434189e-14,2.84217094e-14 L39.1816085,2.84217094e-14 L69.3453773,32.2519224 L101.428699,2.84217094e-14 L138.784583,2.84217094e-14 L138.784199,29.8015838 C137.958931,37.3510206 135.784352,42.5567762 132.260463,45.4188507 C128.736573,48.2809251 112.33867,64.5239941 83.0667527,94.1480575 L56.2750821,94.1480575 L6.71554594,44.4188507 C2.46876683,39.9813776 0.345377275,35.1089553 0.345377275,29.8015838 C0.345377275,24.4942122 0.230251516,14.560351 -5.68434189e-14,2.84217094e-14 Z'
|
||||
style={{ fill: 'currentColor' }}
|
||||
></path>
|
||||
<path
|
||||
d='M69.3453773,32.2519224 L101.428699,1.42108547e-14 L138.784583,1.42108547e-14 L138.784199,29.8015838 C137.958931,37.3510206 135.784352,42.5567762 132.260463,45.4188507 C128.736573,48.2809251 112.33867,64.5239941 83.0667527,94.1480575 L56.2750821,94.1480575 L32.8435758,70.5039241 L69.3453773,32.2519224 Z'
|
||||
fill='url(#invoice-linearGradient-1)'
|
||||
opacity='0.2'
|
||||
></path>
|
||||
<polygon
|
||||
fill='#000000'
|
||||
opacity='0.049999997'
|
||||
points='69.3922914 32.4202615 32.8435758 70.5039241 54.0490008 16.1851325'
|
||||
></polygon>
|
||||
<polygon
|
||||
fill='#000000'
|
||||
opacity='0.099999994'
|
||||
points='69.3922914 32.4202615 32.8435758 70.5039241 58.3683556 20.7402338'
|
||||
></polygon>
|
||||
<polygon
|
||||
fill='url(#invoice-linearGradient-2)'
|
||||
opacity='0.099999994'
|
||||
points='101.428699 0 83.0667527 94.1480575 130.378721 47.0740288'
|
||||
></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<h3 className='text-primary invoice-logo'></h3>
|
||||
</div>
|
||||
<p className='card-text mb-25'>Office 149, 450 South Brand Brooklyn</p>
|
||||
<p className='card-text mb-25'>San Diego County, CA 91905, USA</p>
|
||||
<p className='card-text mb-0'>+1 (123) 456 7891, +44 (876) 543 2198</p>
|
||||
</div>
|
||||
<div className='invoice-number-date mt-md-0 mt-2'>
|
||||
<div className='d-flex align-items-center justify-content-md-end mb-1'>
|
||||
<h4 className='invoice-title'>Invoice</h4>
|
||||
<InputGroup className='input-group-merge invoice-edit-input-group disabled'>
|
||||
<InputGroupAddon addonType='prepend'>
|
||||
<InputGroupText>
|
||||
<Hash size={15} />
|
||||
</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<Input
|
||||
type='number'
|
||||
className='invoice-edit-input'
|
||||
value={data.invoice.id}
|
||||
placeholder='53634'
|
||||
disabled
|
||||
/>
|
||||
</InputGroup>
|
||||
</div>
|
||||
<div className='d-flex align-items-center mb-1'>
|
||||
<span className='title'>Date:</span>
|
||||
<Flatpickr
|
||||
value={picker}
|
||||
onChange={date => setPicker(date)}
|
||||
className='form-control invoice-edit-input date-picker'
|
||||
/>
|
||||
</div>
|
||||
<div className='d-flex align-items-center'>
|
||||
<span className='title'>Due Date:</span>
|
||||
<Flatpickr
|
||||
value={dueDatepicker}
|
||||
onChange={date => setDueDatePicker(date)}
|
||||
className='form-control invoice-edit-input due-date-picker'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardBody>
|
||||
{/* /Header */}
|
||||
|
||||
<hr className='invoice-spacing' />
|
||||
|
||||
{/* Address and Contact */}
|
||||
<CardBody className='invoice-padding pt-0'>
|
||||
<Row className='invoice-spacing'>
|
||||
<Col className='p-0' lg='8'>
|
||||
<h6 className='mb-2'>Invoice To:</h6>
|
||||
<h6 className='mb-25'>{data.invoice.client.name}</h6>
|
||||
<CardText className='mb-25'>{data.invoice.client.company}</CardText>
|
||||
<CardText className='mb-25'>{data.invoice.client.address}</CardText>
|
||||
<CardText className='mb-25'>{data.invoice.client.contact}</CardText>
|
||||
<CardText className='mb-0'>{data.invoice.client.companyEmail}</CardText>
|
||||
</Col>
|
||||
<Col className='p-0 mt-xl-0 mt-2' lg='4'>
|
||||
<h6 className='mb-2'>Payment Details:</h6>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className='pr-1'>Total Due:</td>
|
||||
<td>
|
||||
<span className='font-weight-bolder'>{data.paymentDetails.totalDue}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>Bank name:</td>
|
||||
<td>{data.paymentDetails.bankName}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>Country:</td>
|
||||
<td>{data.paymentDetails.country}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>IBAN:</td>
|
||||
<td>{data.paymentDetails.iban}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>SWIFT code:</td>
|
||||
<td>{data.paymentDetails.swiftCode}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
{/* /Address and Contact */}
|
||||
|
||||
{/* Product Details */}
|
||||
<CardBody className='invoice-padding invoice-product-details'>
|
||||
<Repeater count={count}>
|
||||
{i => {
|
||||
const Tag = i === 0 ? 'div' : SlideDown
|
||||
return (
|
||||
<Tag key={i} className='repeater-wrapper'>
|
||||
<Row>
|
||||
<Col className='d-flex product-details-border position-relative pr-0' sm='12'>
|
||||
<Row className='w-100 pr-lg-0 pr-1 py-2'>
|
||||
<Col className='mb-lg-0 mb-2 mt-lg-0 mt-2' lg='5' sm='12'>
|
||||
<CardText className='col-title mb-md-50 mb-0'>Item</CardText>
|
||||
<Input type='select' className='item-details'>
|
||||
<option>App Design</option>
|
||||
<option>App Customization</option>
|
||||
<option>ABC Template</option>
|
||||
<option>App Development</option>
|
||||
</Input>
|
||||
<Input className='mt-2' type='textarea' rows='1' defaultValue='Customization & Bug Fixes' />
|
||||
</Col>
|
||||
<Col className='my-lg-0 my-2' lg='3' sm='12'>
|
||||
<CardText className='col-title mb-md-2 mb-0'>Cost</CardText>
|
||||
<Input type='number' defaultValue='24' placeholder='24' />
|
||||
<div className='mt-2'>
|
||||
<span>Discount:</span> <span>0%</span>
|
||||
<span id={`tax1-${i}`} className='ml-50'>
|
||||
0%
|
||||
</span>
|
||||
<span id={`tax2-${i}`} className='ml-50'>
|
||||
0%
|
||||
</span>
|
||||
<UncontrolledTooltip target={`tax1-${i}`}>Tax 1</UncontrolledTooltip>
|
||||
<UncontrolledTooltip target={`tax2-${i}`}>Tax 2</UncontrolledTooltip>
|
||||
</div>
|
||||
</Col>
|
||||
<Col className='my-lg-0 my-2' lg='2' sm='12'>
|
||||
<CardText className='col-title mb-md-2 mb-0'>Qty</CardText>
|
||||
<Input type='number' defaultValue='1' placeholder='1' />
|
||||
</Col>
|
||||
<Col className='my-lg-0 mt-2' lg='2' sm='12'>
|
||||
<CardText className='col-title mb-md-50 mb-0'>Price</CardText>
|
||||
<CardText className='mb-0'>$24.00</CardText>
|
||||
</Col>
|
||||
</Row>
|
||||
<div className='d-flex flex-column align-items-center justify-content-start border-left invoice-product-actions py-50 px-25'>
|
||||
<X size={18} className='cursor-pointer' onClick={deleteForm} />
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Tag>
|
||||
)
|
||||
}}
|
||||
</Repeater>
|
||||
|
||||
<Row className='mt-1'>
|
||||
<Col sm='12' className='px-0'>
|
||||
<Button.Ripple color='primary' size='sm' className='btn-add-new' onClick={() => setCount(count + 1)}>
|
||||
<Plus size={14} className='mr-25'></Plus>
|
||||
<span className='align-middle'>Add Item</span>
|
||||
</Button.Ripple>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
{/* /Product Details */}
|
||||
|
||||
{/* Invoice Total */}
|
||||
<CardBody className='invoice-padding'>
|
||||
<Row className='invoice-sales-total-wrapper'>
|
||||
<Col className='mt-md-0 mt-3' md={{ size: '6', order: 1 }} xs={{ size: 12, order: 2 }}>
|
||||
<div className='d-flex align-items-center mb-1'>
|
||||
<Label for='salesperson' className='form-label'>
|
||||
Salesperson:
|
||||
</Label>
|
||||
<Input type='text' className='ml-50' id='salesperson' placeholder='Edward Crowley' />
|
||||
</div>
|
||||
</Col>
|
||||
<Col className='d-flex justify-content-end' md={{ size: '6', order: 2 }} xs={{ size: 12, order: 1 }}>
|
||||
<div className='invoice-total-wrapper'>
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Subtotal:</p>
|
||||
<p className='invoice-total-amount'>$1800</p>
|
||||
</div>
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Discount:</p>
|
||||
<p className='invoice-total-amount'>$28</p>
|
||||
</div>
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Tax:</p>
|
||||
<p className='invoice-total-amount'>21%</p>
|
||||
</div>
|
||||
<hr className='my-50' />
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Total:</p>
|
||||
<p className='invoice-total-amount'>$1690</p>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
{/* /Invoice Total */}
|
||||
|
||||
<hr className='invoice-spacing mt-0' />
|
||||
|
||||
{/* Invoice Note */}
|
||||
<CardBody className='invoice-padding py-0'>
|
||||
<Row>
|
||||
<Col>
|
||||
<FormGroup className='mb-2'>
|
||||
<Label for='note' className='form-label font-weight-bold'>
|
||||
Note:
|
||||
</Label>
|
||||
<Input type='textarea' rows='2' id='note' defaultValue={note} />
|
||||
</FormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
{/* /Invoice Note */}
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default InvoiceEditCard
|
@ -1,58 +0,0 @@
|
||||
// ** React Imports
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useParams, Link } from 'react-router-dom'
|
||||
|
||||
// ** Third Party Components
|
||||
import axios from 'axios'
|
||||
import { Alert, Row, Col } from 'reactstrap'
|
||||
|
||||
// ** Invoice Edit Components
|
||||
import EditCard from './EditCard'
|
||||
import EditActions from './EditActions'
|
||||
import SendInvoiceSidebar from '../shared-sidebar/SidebarSendInvoice'
|
||||
import AddPaymentSidebar from '../shared-sidebar/SidebarAddPayment'
|
||||
|
||||
const InvoiceEdit = () => {
|
||||
// ** Vars
|
||||
const { id } = useParams()
|
||||
|
||||
// ** States
|
||||
const [data, setData] = useState(null)
|
||||
const [sendSidebarOpen, setSendSidebarOpen] = useState(false)
|
||||
const [addPaymentOpen, setAddPaymentOpen] = useState(false)
|
||||
|
||||
// ** Functions to toggle add & send sidebar
|
||||
const toggleSendSidebar = () => setSendSidebarOpen(!sendSidebarOpen)
|
||||
const toggleAddSidebar = () => setAddPaymentOpen(!addPaymentOpen)
|
||||
|
||||
// ** Get invoice on mount based on id
|
||||
useEffect(() => {
|
||||
axios.get(`/api/invoice/invoices/${id}`).then(response => {
|
||||
setData(response.data)
|
||||
})
|
||||
}, [])
|
||||
|
||||
return data !== null && data.invoice !== undefined ? (
|
||||
<div className='invoice-edit-wrapper'>
|
||||
<Row className='invoice-edit'>
|
||||
<Col xl={9} md={8} sm={12}>
|
||||
<EditCard data={data} />
|
||||
</Col>
|
||||
<Col xl={3} md={4} sm={12}>
|
||||
<EditActions setSendSidebarOpen={setSendSidebarOpen} setAddPaymentOpen={setAddPaymentOpen} />
|
||||
</Col>
|
||||
</Row>
|
||||
<SendInvoiceSidebar toggleSidebar={toggleSendSidebar} open={sendSidebarOpen} />
|
||||
<AddPaymentSidebar toggleSidebar={toggleAddSidebar} open={addPaymentOpen} />
|
||||
</div>
|
||||
) : (
|
||||
<Alert color='danger'>
|
||||
<h4 className='alert-heading'>Invoice not found</h4>
|
||||
<div className='alert-body'>
|
||||
Invoice with id: {id} doesn't exist. Check list of all invoices: <Link to='/invoice/list'>Invoice List</Link>
|
||||
</div>
|
||||
</Alert>
|
||||
)
|
||||
}
|
||||
|
||||
export default InvoiceEdit
|
@ -1,172 +0,0 @@
|
||||
// ** React Imports
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
// ** Table Columns
|
||||
import { columns } from './columns'
|
||||
|
||||
// ** Third Party Components
|
||||
import ReactPaginate from 'react-paginate'
|
||||
import { ChevronDown } from 'react-feather'
|
||||
import DataTable from 'react-data-table-component'
|
||||
import { Button, Label, Input, CustomInput, Row, Col, Card } from 'reactstrap'
|
||||
|
||||
// ** Store & Actions
|
||||
import { getData } from '../store/actions'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
|
||||
// ** Styles
|
||||
import '@styles/react/apps/app-invoice.scss'
|
||||
import '@styles/react/libs/tables/react-dataTable-component.scss'
|
||||
|
||||
const CustomHeader = ({ handleFilter, value, handleStatusValue, statusValue, handlePerPage, rowsPerPage }) => {
|
||||
return (
|
||||
<div className='invoice-list-table-header w-100 py-2'>
|
||||
<Row>
|
||||
<Col lg='6' className='d-flex align-items-center px-0 px-lg-1'>
|
||||
<div class="card-header"><h4 class="card-title">Search Filter</h4></div>
|
||||
|
||||
<Input className='w-auto ' type='select' value={statusValue} onChange={handleStatusValue}>
|
||||
<option value=''>Select Status</option>
|
||||
<option value='pending'>Pending</option>
|
||||
<option value='active'>Active</option>
|
||||
<option value='inactive'>Inactive</option>
|
||||
|
||||
</Input>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const SearchFilter = () => {
|
||||
const dispatch = useDispatch()
|
||||
const store = useSelector(state => state.invoice)
|
||||
|
||||
const [value, setValue] = useState('')
|
||||
const [currentPage, setCurrentPage] = useState(1)
|
||||
const [statusValue, setStatusValue] = useState('')
|
||||
const [rowsPerPage, setRowsPerPage] = useState(10)
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
getData({
|
||||
page: currentPage,
|
||||
perPage: rowsPerPage,
|
||||
status: statusValue,
|
||||
q: value
|
||||
})
|
||||
)
|
||||
}, [dispatch, store.data.length])
|
||||
|
||||
const handleFilter = val => {
|
||||
setValue(val)
|
||||
dispatch(
|
||||
getData({
|
||||
page: currentPage,
|
||||
perPage: rowsPerPage,
|
||||
status: statusValue,
|
||||
q: val
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const handlePerPage = e => {
|
||||
dispatch(
|
||||
getData({
|
||||
page: currentPage,
|
||||
perPage: parseInt(e.target.value),
|
||||
status: statusValue,
|
||||
q: value
|
||||
})
|
||||
)
|
||||
setRowsPerPage(parseInt(e.target.value))
|
||||
}
|
||||
|
||||
const handleStatusValue = e => {
|
||||
setStatusValue(e.target.value)
|
||||
dispatch(
|
||||
getData({
|
||||
page: currentPage,
|
||||
perPage: rowsPerPage,
|
||||
status: e.target.value,
|
||||
q: value
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const handlePagination = page => {
|
||||
dispatch(
|
||||
getData({
|
||||
page: page.selected + 1,
|
||||
perPage: rowsPerPage,
|
||||
status: statusValue,
|
||||
q: value
|
||||
})
|
||||
)
|
||||
setCurrentPage(page.selected + 1)
|
||||
}
|
||||
|
||||
const CustomPagination = () => {
|
||||
const count = Number((store.total / rowsPerPage).toFixed(0))
|
||||
|
||||
return (
|
||||
<ReactPaginate
|
||||
pageCount={count || 1}
|
||||
nextLabel=''
|
||||
breakLabel='...'
|
||||
previousLabel=''
|
||||
activeClassName='active'
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
forcePage={currentPage !== 0 ? currentPage - 1 : 0}
|
||||
onPageChange={page => handlePagination(page)}
|
||||
pageClassName={'page-item'}
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next'}
|
||||
previousClassName={'page-item prev'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
containerClassName={'pagination react-paginate justify-content-end p-1'}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const dataToRender = () => {
|
||||
const filters = {
|
||||
status: statusValue,
|
||||
q: value
|
||||
}
|
||||
|
||||
const isFiltered = Object.keys(filters).some(function (k) {
|
||||
return filters[k].length > 0
|
||||
})
|
||||
|
||||
if (store.data.length > 0) {
|
||||
return store.data
|
||||
} else if (store.data.length === 0 && isFiltered) {
|
||||
return []
|
||||
} else {
|
||||
return store.allData.slice(0, rowsPerPage)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='invoice-list-wrapper'>
|
||||
<Card>
|
||||
<div className='invoice-list-dataTable'>
|
||||
<CustomHeader
|
||||
value={value}
|
||||
statusValue={statusValue}
|
||||
rowsPerPage={rowsPerPage}
|
||||
handleFilter={handleFilter}
|
||||
handlePerPage={handlePerPage}
|
||||
handleStatusValue={handleStatusValue}
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SearchFilter
|
@ -1,158 +0,0 @@
|
||||
// ** React Import
|
||||
import { useState } from 'react'
|
||||
|
||||
// ** Custom Components
|
||||
import Sidebar from '@components/sidebar'
|
||||
|
||||
// ** Utils
|
||||
import { isObjEmpty } from '@utils'
|
||||
|
||||
// ** Third Party Components
|
||||
import classnames from 'classnames'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import { Button, FormGroup, Label, FormText, Form, Input } from 'reactstrap'
|
||||
|
||||
// ** Store & Actions
|
||||
// import { addUser } from '../store/action'
|
||||
import { useDispatch } from 'react-redux'
|
||||
|
||||
const SidebarNewUsers = ({ open, toggleSidebar }) => {
|
||||
// ** States
|
||||
const [role, setRole] = useState('subscriber')
|
||||
const [plan, setPlan] = useState('basic')
|
||||
|
||||
// ** Store Vars
|
||||
const dispatch = useDispatch()
|
||||
|
||||
// ** Vars
|
||||
// const { register, errors, handleSubmit } = useForm()
|
||||
|
||||
// ** Function to handle form submit
|
||||
const onSubmit = values => {
|
||||
if (isObjEmpty(errors)) {
|
||||
toggleSidebar()
|
||||
dispatch(
|
||||
addUser({
|
||||
fullName: values['full-name'],
|
||||
company: values.company,
|
||||
role,
|
||||
username: values.username,
|
||||
country: values.country,
|
||||
contact: values.contact,
|
||||
email: values.email,
|
||||
currentPlan: plan,
|
||||
status: 'active',
|
||||
avatar: ''
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Sidebar
|
||||
size='lg'
|
||||
open={open}
|
||||
title='New User'
|
||||
headerClassName='mb-1'
|
||||
contentClassName='pt-0'
|
||||
toggleSidebar={toggleSidebar}
|
||||
>
|
||||
<Form >
|
||||
<FormGroup>
|
||||
<Label for='full-name'>
|
||||
Full Name <span className='text-danger'>*</span>
|
||||
</Label>
|
||||
<Input
|
||||
name='full-name'
|
||||
id='full-name'
|
||||
placeholder='John Doe'
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='username'>
|
||||
Username <span className='text-danger'>*</span>
|
||||
</Label>
|
||||
<Input
|
||||
name='username'
|
||||
id='username'
|
||||
placeholder='johnDoe99'
|
||||
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='email'>
|
||||
Email <span className='text-danger'>*</span>
|
||||
</Label>
|
||||
<Input
|
||||
type='email'
|
||||
name='email'
|
||||
id='email'
|
||||
placeholder='john.doe@example.com'
|
||||
|
||||
/>
|
||||
<FormText color='muted'>You can use letters, numbers & periods</FormText>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='company'>
|
||||
Company <span className='text-danger'>*</span>
|
||||
</Label>
|
||||
<Input
|
||||
name='company'
|
||||
id='company'
|
||||
placeholder='Company Pvt Ltd'
|
||||
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='country'>
|
||||
Country <span className='text-danger'>*</span>
|
||||
</Label>
|
||||
<Input
|
||||
name='country'
|
||||
id='country'
|
||||
placeholder='Australia'
|
||||
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='contact'>
|
||||
Contact <span className='text-danger'>*</span>
|
||||
</Label>
|
||||
<Input
|
||||
name='contact'
|
||||
id='contact'
|
||||
placeholder='(397) 294-5153'
|
||||
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='user-role'>User Role</Label>
|
||||
<Input type='select' id='user-role' name='user-role' value={role} onChange={e => setRole(e.target.value)}>
|
||||
<option value='subscriber'>Subscriber</option>
|
||||
<option value='editor'>Editor</option>
|
||||
<option value='maintainer'>Maintainer</option>
|
||||
<option value='author'>Author</option>
|
||||
<option value='admin'>Admin</option>
|
||||
</Input>
|
||||
</FormGroup>
|
||||
<FormGroup className='mb-2' value={plan} onChange={e => setPlan(e.target.value)}>
|
||||
<Label for='select-plan'>Select Plan</Label>
|
||||
<Input type='select' id='select-plan' name='select-plan'>
|
||||
<option value='basic'>Basic</option>
|
||||
<option value='enterprise'>Enterprise</option>
|
||||
<option value='company'>Company</option>
|
||||
<option value='team'>Team</option>
|
||||
</Input>
|
||||
</FormGroup>
|
||||
<Button type='submit' className='mr-1' color='primary'>
|
||||
Submit
|
||||
</Button>
|
||||
<Button type='reset' color='secondary' outline onClick={toggleSidebar}>
|
||||
Cancel
|
||||
</Button>
|
||||
</Form>
|
||||
</Sidebar>
|
||||
)
|
||||
}
|
||||
|
||||
export default SidebarNewUsers
|
@ -1,190 +0,0 @@
|
||||
// ** React Imports
|
||||
import { Fragment } from 'react'
|
||||
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
// ** Custom Components
|
||||
import Avatar from '@components/avatar'
|
||||
|
||||
// ** Store & Actions
|
||||
import { deleteInvoice } from '../store/actions'
|
||||
import { store } from '@store/storeConfig/store'
|
||||
|
||||
// ** Third Party Components
|
||||
import {
|
||||
Badge,
|
||||
UncontrolledDropdown,
|
||||
DropdownMenu,
|
||||
DropdownToggle,
|
||||
DropdownItem,
|
||||
UncontrolledTooltip
|
||||
} from 'reactstrap'
|
||||
import {
|
||||
Eye,
|
||||
TrendingUp,
|
||||
Send,
|
||||
MoreVertical,
|
||||
Download,
|
||||
Edit,
|
||||
Trash,
|
||||
Copy,
|
||||
CheckCircle,
|
||||
Save,
|
||||
ArrowDownCircle,
|
||||
Info,
|
||||
PieChart
|
||||
} from 'react-feather'
|
||||
|
||||
// ** Vars
|
||||
const invoiceStatusObj = {
|
||||
Sent: { color: 'light-secondary', icon: Send },
|
||||
Paid: { color: 'light-success', icon: CheckCircle },
|
||||
Draft: { color: 'light-primary', icon: Save },
|
||||
Downloaded: { color: 'light-info', icon: ArrowDownCircle },
|
||||
'Past Due': { color: 'light-danger', icon: Info },
|
||||
'Partial Payment': { color: 'light-warning', icon: PieChart }
|
||||
}
|
||||
|
||||
// ** renders client column
|
||||
const renderClient = row => {
|
||||
const stateNum = Math.floor(Math.random() * 6),
|
||||
states = ['light-success', 'light-danger', 'light-warning', 'light-info', 'light-primary', 'light-secondary'],
|
||||
color = states[stateNum]
|
||||
|
||||
if (row.avatar.length) {
|
||||
return <Avatar className='mr-50' img={row.avatar} width='32' height='32' />
|
||||
} else {
|
||||
return <Avatar color={color} className='mr-50' content={row.client ? row.client.name : 'John Doe'} initials />
|
||||
}
|
||||
}
|
||||
|
||||
// ** Table columns
|
||||
export const columns = [
|
||||
{
|
||||
name: '#',
|
||||
minWidth: '107px',
|
||||
selector: 'id',
|
||||
cell: row => <Link to={`/apps/invoice/preview/${row.id}`}>{`#${row.id}`}</Link>
|
||||
},
|
||||
{
|
||||
name: <TrendingUp size={14} />,
|
||||
minWidth: '102px',
|
||||
selector: 'invoiceStatus',
|
||||
sortable: true,
|
||||
cell: row => {
|
||||
const color = invoiceStatusObj[row.invoiceStatus] ? invoiceStatusObj[row.invoiceStatus].color : 'primary',
|
||||
Icon = invoiceStatusObj[row.invoiceStatus] ? invoiceStatusObj[row.invoiceStatus].icon : Edit
|
||||
return (
|
||||
<Fragment>
|
||||
<Avatar color={color} icon={<Icon size={14} />} id={`av-tooltip-${row.id}`} />
|
||||
<UncontrolledTooltip placement='top' target={`av-tooltip-${row.id}`}>
|
||||
<span className='font-weight-bold'>{row.invoiceStatus}</span>
|
||||
<br />
|
||||
<span className='font-weight-bold'>Balance:</span> {row.balance}
|
||||
<br />
|
||||
<span className='font-weight-bold'>Due Date:</span> {row.dueDate}
|
||||
</UncontrolledTooltip>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Client',
|
||||
minWidth: '350px',
|
||||
selector: 'client',
|
||||
sortable: true,
|
||||
cell: row => {
|
||||
const name = row.client ? row.client.name : 'John Doe',
|
||||
email = row.client ? row.client.companyEmail : 'johnDoe@email.com'
|
||||
return (
|
||||
<div className='d-flex justify-content-left align-items-center'>
|
||||
{renderClient(row)}
|
||||
<div className='d-flex flex-column'>
|
||||
<h6 className='user-name text-truncate mb-0'>{name}</h6>
|
||||
<small className='text-truncate text-muted mb-0'>{email}</small>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Total',
|
||||
selector: 'total',
|
||||
sortable: true,
|
||||
minWidth: '150px',
|
||||
cell: row => <span>${row.total || 0}</span>
|
||||
},
|
||||
{
|
||||
name: 'Issued Date',
|
||||
selector: 'dueDate',
|
||||
sortable: true,
|
||||
minWidth: '200px',
|
||||
cell: row => row.dueDate
|
||||
},
|
||||
{
|
||||
name: 'Balance',
|
||||
selector: 'balance',
|
||||
sortable: true,
|
||||
minWidth: '164px',
|
||||
cell: row => {
|
||||
return row.balance !== 0 ? (
|
||||
<span>{row.balance}</span>
|
||||
) : (
|
||||
<Badge color='light-success' pill>
|
||||
Paid
|
||||
</Badge>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Action',
|
||||
minWidth: '110px',
|
||||
selector: '',
|
||||
sortable: true,
|
||||
cell: row => (
|
||||
<div className='column-action d-flex align-items-center'>
|
||||
<Send size={17} id={`send-tooltip-${row.id}`} />
|
||||
<UncontrolledTooltip placement='top' target={`send-tooltip-${row.id}`}>
|
||||
Send Mail
|
||||
</UncontrolledTooltip>
|
||||
<Link to={`/apps/invoice/preview/${row.id}`} id={`pw-tooltip-${row.id}`}>
|
||||
<Eye size={17} className='mx-1' />
|
||||
</Link>
|
||||
<UncontrolledTooltip placement='top' target={`pw-tooltip-${row.id}`}>
|
||||
Preview Invoice
|
||||
</UncontrolledTooltip>
|
||||
<UncontrolledDropdown>
|
||||
<DropdownToggle tag='span'>
|
||||
<MoreVertical size={17} className='cursor-pointer' />
|
||||
</DropdownToggle>
|
||||
<DropdownMenu right>
|
||||
<DropdownItem tag='a' href='/' className='w-100' onClick={e => e.preventDefault()}>
|
||||
<Download size={14} className='mr-50' />
|
||||
<span className='align-middle'>Download</span>
|
||||
</DropdownItem>
|
||||
<DropdownItem tag={Link} to={`/apps/invoice/edit/${row.id}`} className='w-100'>
|
||||
<Edit size={14} className='mr-50' />
|
||||
<span className='align-middle'>Edit</span>
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
tag='a'
|
||||
href='/'
|
||||
className='w-100'
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
store.dispatch(deleteInvoice(row.id))
|
||||
}}
|
||||
>
|
||||
<Trash size={14} className='mr-50' />
|
||||
<span className='align-middle'>Delete</span>
|
||||
</DropdownItem>
|
||||
<DropdownItem tag='a' href='/' className='w-100' onClick={e => e.preventDefault()}>
|
||||
<Copy size={14} className='mr-50' />
|
||||
<span className='align-middle'>Duplicate</span>
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</UncontrolledDropdown>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
]
|
@ -1,221 +0,0 @@
|
||||
// ** React Imports
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
// ** Table Columns
|
||||
import { columns } from './columns'
|
||||
|
||||
// ** Third Party Components
|
||||
import ReactPaginate from 'react-paginate'
|
||||
import { ChevronDown } from 'react-feather'
|
||||
import DataTable from 'react-data-table-component'
|
||||
import { Button, Label, Input, CustomInput, Row, Col, Card } from 'reactstrap'
|
||||
|
||||
// ** Store & Actions
|
||||
import { getData } from '../store/actions'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
|
||||
// ** Styles
|
||||
import '@styles/react/apps/app-invoice.scss'
|
||||
import '@styles/react/libs/tables/react-dataTable-component.scss'
|
||||
|
||||
const CustomHeader = ({ handleFilter, value, handleStatusValue, statusValue, handlePerPage, rowsPerPage }) => {
|
||||
return (
|
||||
<div className='invoice-list-table-header w-100 py-2'>
|
||||
<Row>
|
||||
<Col lg='6' className='d-flex align-items-center px-0 px-lg-1'>
|
||||
<div className='d-flex align-items-center mr-2'>
|
||||
<Label for='rows-per-page'>Show</Label>
|
||||
<CustomInput
|
||||
className='form-control ml-50 pr-3'
|
||||
type='select'
|
||||
id='rows-per-page'
|
||||
value={rowsPerPage}
|
||||
onChange={handlePerPage}
|
||||
>
|
||||
<option value='10'>10</option>
|
||||
<option value='25'>25</option>
|
||||
<option value='50'>50</option>
|
||||
</CustomInput>
|
||||
</div>
|
||||
<Button.Ripple tag={Link} to='/apps/invoice/add' color='primary'>
|
||||
Add Record
|
||||
</Button.Ripple>
|
||||
</Col>
|
||||
<Col
|
||||
lg='6'
|
||||
className='actions-right d-flex align-items-center justify-content-lg-end flex-lg-nowrap flex-wrap mt-lg-0 mt-1 pr-lg-1 p-0'
|
||||
>
|
||||
<div className='d-flex align-items-center'>
|
||||
<Label for='search-invoice'>Search</Label>
|
||||
<Input
|
||||
id='search-invoice'
|
||||
className='ml-50 mr-2 w-100'
|
||||
type='text'
|
||||
value={value}
|
||||
onChange={e => handleFilter(e.target.value)}
|
||||
placeholder='Search Invoice'
|
||||
/>
|
||||
</div>
|
||||
<Input className='w-auto ' type='select' value={statusValue} onChange={handleStatusValue}>
|
||||
<option value=''>Select Status</option>
|
||||
<option value='downloaded'>Downloaded</option>
|
||||
<option value='draft'>Draft</option>
|
||||
<option value='paid'>Paid</option>
|
||||
<option value='partial payment'>Partial Payment</option>
|
||||
<option value='past due'>Past Due</option>
|
||||
<option value='partial payment'>Partial Payment</option>
|
||||
</Input>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const InvoiceList = () => {
|
||||
const dispatch = useDispatch()
|
||||
const store = useSelector(state => state.invoice)
|
||||
|
||||
const [value, setValue] = useState('')
|
||||
const [currentPage, setCurrentPage] = useState(1)
|
||||
const [statusValue, setStatusValue] = useState('')
|
||||
const [rowsPerPage, setRowsPerPage] = useState(10)
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
getData({
|
||||
page: currentPage,
|
||||
perPage: rowsPerPage,
|
||||
status: statusValue,
|
||||
q: value
|
||||
})
|
||||
)
|
||||
}, [dispatch, store.data.length])
|
||||
|
||||
const handleFilter = val => {
|
||||
setValue(val)
|
||||
dispatch(
|
||||
getData({
|
||||
page: currentPage,
|
||||
perPage: rowsPerPage,
|
||||
status: statusValue,
|
||||
q: val
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const handlePerPage = e => {
|
||||
dispatch(
|
||||
getData({
|
||||
page: currentPage,
|
||||
perPage: parseInt(e.target.value),
|
||||
status: statusValue,
|
||||
q: value
|
||||
})
|
||||
)
|
||||
setRowsPerPage(parseInt(e.target.value))
|
||||
}
|
||||
|
||||
const handleStatusValue = e => {
|
||||
setStatusValue(e.target.value)
|
||||
dispatch(
|
||||
getData({
|
||||
page: currentPage,
|
||||
perPage: rowsPerPage,
|
||||
status: e.target.value,
|
||||
q: value
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const handlePagination = page => {
|
||||
dispatch(
|
||||
getData({
|
||||
page: page.selected + 1,
|
||||
perPage: rowsPerPage,
|
||||
status: statusValue,
|
||||
q: value
|
||||
})
|
||||
)
|
||||
setCurrentPage(page.selected + 1)
|
||||
}
|
||||
|
||||
const CustomPagination = () => {
|
||||
const count = Number((store.total / rowsPerPage).toFixed(0))
|
||||
|
||||
return (
|
||||
<ReactPaginate
|
||||
pageCount={count || 1}
|
||||
nextLabel=''
|
||||
breakLabel='...'
|
||||
previousLabel=''
|
||||
activeClassName='active'
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
forcePage={currentPage !== 0 ? currentPage - 1 : 0}
|
||||
onPageChange={page => handlePagination(page)}
|
||||
pageClassName={'page-item'}
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next'}
|
||||
previousClassName={'page-item prev'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
containerClassName={'pagination react-paginate justify-content-end p-1'}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const dataToRender = () => {
|
||||
const filters = {
|
||||
status: statusValue,
|
||||
q: value
|
||||
}
|
||||
|
||||
const isFiltered = Object.keys(filters).some(function (k) {
|
||||
return filters[k].length > 0
|
||||
})
|
||||
|
||||
if (store.data.length > 0) {
|
||||
return store.data
|
||||
} else if (store.data.length === 0 && isFiltered) {
|
||||
return []
|
||||
} else {
|
||||
return store.allData.slice(0, rowsPerPage)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='invoice-list-wrapper'>
|
||||
<Card>
|
||||
<div className='invoice-list-dataTable'>
|
||||
<DataTable
|
||||
noHeader
|
||||
pagination
|
||||
paginationServer
|
||||
subHeader={true}
|
||||
columns={columns}
|
||||
responsive={true}
|
||||
sortIcon={<ChevronDown />}
|
||||
className='react-dataTable'
|
||||
defaultSortField='invoiceId'
|
||||
paginationDefaultPage={currentPage}
|
||||
paginationComponent={CustomPagination}
|
||||
data={dataToRender()}
|
||||
subHeaderComponent={
|
||||
<CustomHeader
|
||||
value={value}
|
||||
statusValue={statusValue}
|
||||
rowsPerPage={rowsPerPage}
|
||||
handleFilter={handleFilter}
|
||||
handlePerPage={handlePerPage}
|
||||
handleStatusValue={handleStatusValue}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default InvoiceList
|
@ -1,39 +0,0 @@
|
||||
// ** React Imports
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
// ** Third Party Components
|
||||
import { Card, CardBody, Button } from 'reactstrap'
|
||||
|
||||
const PreviewActions = ({ id, setSendSidebarOpen, setAddPaymentOpen }) => {
|
||||
return (
|
||||
<Card className='invoice-action-wrapper'>
|
||||
<CardBody>
|
||||
<Button.Ripple color='primary' block className='mb-75' onClick={() => setSendSidebarOpen(true)}>
|
||||
Send Invoice
|
||||
</Button.Ripple>
|
||||
<Button.Ripple color='secondary' block outline className='mb-75'>
|
||||
Download
|
||||
</Button.Ripple>
|
||||
<Button.Ripple
|
||||
color='secondary'
|
||||
tag={Link}
|
||||
to='/apps/invoice/print'
|
||||
target='_blank'
|
||||
block
|
||||
outline
|
||||
className='mb-75'
|
||||
>
|
||||
Print
|
||||
</Button.Ripple>
|
||||
<Button.Ripple tag={Link} to={`/apps/invoice/edit/${id}`} color='secondary' block outline className='mb-75'>
|
||||
Edit
|
||||
</Button.Ripple>
|
||||
<Button.Ripple color='success' block onClick={() => setAddPaymentOpen(true)}>
|
||||
Add Payment
|
||||
</Button.Ripple>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default PreviewActions
|
@ -1,229 +0,0 @@
|
||||
// ** Third Party Components
|
||||
import { Card, CardBody, CardText, Row, Col, Table } from 'reactstrap'
|
||||
|
||||
const PreviewCard = ({ data }) => {
|
||||
return data !== null ? (
|
||||
<Card className='invoice-preview-card'>
|
||||
<CardBody className='invoice-padding pb-0'>
|
||||
{/* Header */}
|
||||
<div className='d-flex justify-content-between flex-md-row flex-column invoice-spacing mt-0'>
|
||||
<div>
|
||||
<div className='logo-wrapper'>
|
||||
<svg viewBox='0 0 139 95' version='1.1' height='24'>
|
||||
<defs>
|
||||
<linearGradient id='invoice-linearGradient-1' x1='100%' y1='10.5120544%' x2='50%' y2='89.4879456%'>
|
||||
<stop stopColor='#000000' offset='0%'></stop>
|
||||
<stop stopColor='#FFFFFF' offset='100%'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id='invoice-linearGradient-2'
|
||||
x1='64.0437835%'
|
||||
y1='46.3276743%'
|
||||
x2='37.373316%'
|
||||
y2='100%'
|
||||
>
|
||||
<stop stopColor='#EEEEEE' stopOpacity='0' offset='0%'></stop>
|
||||
<stop stopColor='#FFFFFF' offset='100%'></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g stroke='none' strokeWidth='1' fill='none' fillRule='evenodd'>
|
||||
<g transform='translate(-400.000000, -178.000000)'>
|
||||
<g transform='translate(400.000000, 178.000000)'>
|
||||
<path
|
||||
className='text-primary'
|
||||
d='M-5.68434189e-14,2.84217094e-14 L39.1816085,2.84217094e-14 L69.3453773,32.2519224 L101.428699,2.84217094e-14 L138.784583,2.84217094e-14 L138.784199,29.8015838 C137.958931,37.3510206 135.784352,42.5567762 132.260463,45.4188507 C128.736573,48.2809251 112.33867,64.5239941 83.0667527,94.1480575 L56.2750821,94.1480575 L6.71554594,44.4188507 C2.46876683,39.9813776 0.345377275,35.1089553 0.345377275,29.8015838 C0.345377275,24.4942122 0.230251516,14.560351 -5.68434189e-14,2.84217094e-14 Z'
|
||||
style={{ fill: 'currentColor' }}
|
||||
></path>
|
||||
<path
|
||||
d='M69.3453773,32.2519224 L101.428699,1.42108547e-14 L138.784583,1.42108547e-14 L138.784199,29.8015838 C137.958931,37.3510206 135.784352,42.5567762 132.260463,45.4188507 C128.736573,48.2809251 112.33867,64.5239941 83.0667527,94.1480575 L56.2750821,94.1480575 L32.8435758,70.5039241 L69.3453773,32.2519224 Z'
|
||||
fill='url(#invoice-linearGradient-1)'
|
||||
opacity='0.2'
|
||||
></path>
|
||||
<polygon
|
||||
fill='#000000'
|
||||
opacity='0.049999997'
|
||||
points='69.3922914 32.4202615 32.8435758 70.5039241 54.0490008 16.1851325'
|
||||
></polygon>
|
||||
<polygon
|
||||
fill='#000000'
|
||||
opacity='0.099999994'
|
||||
points='69.3922914 32.4202615 32.8435758 70.5039241 58.3683556 20.7402338'
|
||||
></polygon>
|
||||
<polygon
|
||||
fill='url(#invoice-linearGradient-2)'
|
||||
opacity='0.099999994'
|
||||
points='101.428699 0 83.0667527 94.1480575 130.378721 47.0740288'
|
||||
></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<h3 className='text-primary invoice-logo'></h3>
|
||||
</div>
|
||||
<CardText className='mb-25'>Office 149, 450 South Brand Brooklyn</CardText>
|
||||
<CardText className='mb-25'>San Diego County, CA 91905, USA</CardText>
|
||||
<CardText className='mb-0'>+1 (123) 456 7891, +44 (876) 543 2198</CardText>
|
||||
</div>
|
||||
<div className='mt-md-0 mt-2'>
|
||||
<h4 className='invoice-title'>
|
||||
Invoice <span className='invoice-number'>#{data.invoice.id}</span>
|
||||
</h4>
|
||||
<div className='invoice-date-wrapper'>
|
||||
<p className='invoice-date-title'>Date Issued:</p>
|
||||
<p className='invoice-date'>{data.invoice.issuedDate}</p>
|
||||
</div>
|
||||
<div className='invoice-date-wrapper'>
|
||||
<p className='invoice-date-title'>Due Date:</p>
|
||||
<p className='invoice-date'>{data.invoice.dueDate}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* /Header */}
|
||||
</CardBody>
|
||||
|
||||
<hr className='invoice-spacing' />
|
||||
|
||||
{/* Address and Contact */}
|
||||
<CardBody className='invoice-padding pt-0'>
|
||||
<Row className='invoice-spacing'>
|
||||
<Col className='p-0' lg='8'>
|
||||
<h6 className='mb-2'>Invoice To:</h6>
|
||||
<h6 className='mb-25'>{data.invoice.client.name}</h6>
|
||||
<CardText className='mb-25'>{data.invoice.client.company}</CardText>
|
||||
<CardText className='mb-25'>{data.invoice.client.address}</CardText>
|
||||
<CardText className='mb-25'>{data.invoice.client.contact}</CardText>
|
||||
<CardText className='mb-0'>{data.invoice.client.companyEmail}</CardText>
|
||||
</Col>
|
||||
<Col className='p-0 mt-xl-0 mt-2' lg='4'>
|
||||
<h6 className='mb-2'>Payment Details:</h6>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className='pr-1'>Total Due:</td>
|
||||
<td>
|
||||
<span className='font-weight-bolder'>{data.paymentDetails.totalDue}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>Bank name:</td>
|
||||
<td>{data.paymentDetails.bankName}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>Country:</td>
|
||||
<td>{data.paymentDetails.country}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>IBAN:</td>
|
||||
<td>{data.paymentDetails.iban}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>SWIFT code:</td>
|
||||
<td>{data.paymentDetails.swiftCode}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
{/* /Address and Contact */}
|
||||
|
||||
{/* Invoice Description */}
|
||||
<Table responsive>
|
||||
<thead>
|
||||
<tr>
|
||||
<th className='py-1'>Task description</th>
|
||||
<th className='py-1'>Rate</th>
|
||||
<th className='py-1'>Hours</th>
|
||||
<th className='py-1'>Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className='py-1'>
|
||||
<p className='card-text font-weight-bold mb-25'>Native App Development</p>
|
||||
<p className='card-text text-nowrap'>
|
||||
Developed a full stack native app using React Native, Bootstrap & Python
|
||||
</p>
|
||||
</td>
|
||||
<td className='py-1'>
|
||||
<span className='font-weight-bold'>$60.00</span>
|
||||
</td>
|
||||
<td className='py-1'>
|
||||
<span className='font-weight-bold'>30</span>
|
||||
</td>
|
||||
<td className='py-1'>
|
||||
<span className='font-weight-bold'>$1,800.00</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className='border-bottom'>
|
||||
<td className='py-1'>
|
||||
<p className='card-text font-weight-bold mb-25'>Ui Kit Design</p>
|
||||
<p className='card-text text-nowrap'>Designed a UI kit for native app using Sketch, Figma & Adobe XD</p>
|
||||
</td>
|
||||
<td className='py-1'>
|
||||
<span className='font-weight-bold'>$60.00</span>
|
||||
</td>
|
||||
<td className='py-1'>
|
||||
<span className='font-weight-bold'>20</span>
|
||||
</td>
|
||||
<td className='py-1'>
|
||||
<span className='font-weight-bold'>$1200.00</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</Table>
|
||||
{/* /Invoice Description */}
|
||||
|
||||
{/* Total & Sales Person */}
|
||||
<CardBody className='invoice-padding pb-0'>
|
||||
<Row className='invoice-sales-total-wrapper'>
|
||||
<Col className='mt-md-0 mt-3' md='6' order={{ md: 1, lg: 2 }}>
|
||||
<CardText className='mb-0'>
|
||||
<span className='font-weight-bold'>Salesperson:</span> <span className='ml-75'>Alfie Solomons</span>
|
||||
</CardText>
|
||||
</Col>
|
||||
<Col className='d-flex justify-content-end' md='6' order={{ md: 2, lg: 1 }}>
|
||||
<div className='invoice-total-wrapper'>
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Subtotal:</p>
|
||||
<p className='invoice-total-amount'>$1800</p>
|
||||
</div>
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Discount:</p>
|
||||
<p className='invoice-total-amount'>$28</p>
|
||||
</div>
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Tax:</p>
|
||||
<p className='invoice-total-amount'>21%</p>
|
||||
</div>
|
||||
<hr className='my-50' />
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Total:</p>
|
||||
<p className='invoice-total-amount'>$1690</p>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
{/* /Total & Sales Person */}
|
||||
|
||||
<hr className='invoice-spacing' />
|
||||
|
||||
{/* Invoice Note */}
|
||||
<CardBody className='invoice-padding pt-0'>
|
||||
<Row>
|
||||
<Col sm='12'>
|
||||
<span className='font-weight-bold'>Note: </span>
|
||||
<span>
|
||||
It was a pleasure working with you and your team. We hope you will keep us in mind for future freelance
|
||||
projects. Thank You!
|
||||
</span>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
{/* /Invoice Note */}
|
||||
</Card>
|
||||
) : null
|
||||
}
|
||||
|
||||
export default PreviewCard
|
@ -1,60 +0,0 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useParams, Link } from 'react-router-dom'
|
||||
|
||||
// ** Third Party Components
|
||||
import axios from 'axios'
|
||||
import { Row, Col, Alert } from 'reactstrap'
|
||||
|
||||
// ** Invoice Preview Components
|
||||
import PreviewCard from './PreviewCard'
|
||||
import PreviewActions from './PreviewActions'
|
||||
import SendInvoiceSidebar from '../shared-sidebar/SidebarSendInvoice'
|
||||
import AddPaymentSidebar from '../shared-sidebar/SidebarAddPayment'
|
||||
|
||||
// ** Styles
|
||||
import '@styles/base/pages/app-invoice.scss'
|
||||
|
||||
const InvoicePreview = () => {
|
||||
// ** Vars
|
||||
const { id } = useParams()
|
||||
|
||||
// ** States
|
||||
const [data, setData] = useState(null)
|
||||
const [sendSidebarOpen, setSendSidebarOpen] = useState(false)
|
||||
const [addPaymentOpen, setAddPaymentOpen] = useState(false)
|
||||
|
||||
// ** Functions to toggle add & send sidebar
|
||||
const toggleSendSidebar = () => setSendSidebarOpen(!sendSidebarOpen)
|
||||
const toggleAddSidebar = () => setAddPaymentOpen(!addPaymentOpen)
|
||||
|
||||
// ** Get invoice on mount based on id
|
||||
useEffect(() => {
|
||||
axios.get(`/api/invoice/invoices/${id}`).then(response => {
|
||||
setData(response.data)
|
||||
})
|
||||
}, [])
|
||||
|
||||
return data !== null && data.invoice !== undefined ? (
|
||||
<div className='invoice-preview-wrapper'>
|
||||
<Row className='invoice-preview'>
|
||||
<Col xl={9} md={8} sm={12}>
|
||||
<PreviewCard data={data} />
|
||||
</Col>
|
||||
<Col xl={3} md={4} sm={12}>
|
||||
<PreviewActions id={id} setSendSidebarOpen={setSendSidebarOpen} setAddPaymentOpen={setAddPaymentOpen} />
|
||||
</Col>
|
||||
</Row>
|
||||
<SendInvoiceSidebar toggleSidebar={toggleSendSidebar} open={sendSidebarOpen} />
|
||||
<AddPaymentSidebar toggleSidebar={toggleAddSidebar} open={addPaymentOpen} />
|
||||
</div>
|
||||
) : (
|
||||
<Alert color='danger'>
|
||||
<h4 className='alert-heading'>Invoice not found</h4>
|
||||
<div className='alert-body'>
|
||||
Invoice with id: {id} doesn't exist. Check list of all invoices: <Link to='/invoice/list'>Invoice List</Link>
|
||||
</div>
|
||||
</Alert>
|
||||
)
|
||||
}
|
||||
|
||||
export default InvoicePreview
|
@ -1,218 +0,0 @@
|
||||
// ** React Imports
|
||||
import { useEffect } from 'react'
|
||||
|
||||
// ** Third Party Components
|
||||
import { Row, Col, Table } from 'reactstrap'
|
||||
|
||||
// ** Styles
|
||||
import '@styles/base/pages/app-invoice-print.scss'
|
||||
|
||||
const Print = () => {
|
||||
// ** Print on mount
|
||||
useEffect(() => window.print(), [])
|
||||
|
||||
return (
|
||||
<div className='invoice-print p-3'>
|
||||
<div className='d-flex justify-content-between flex-md-row flex-column pb-2'>
|
||||
<div>
|
||||
<div className='d-flex mb-1'>
|
||||
<svg viewBox='0 0 139 95' version='1.1' height='24'>
|
||||
<defs>
|
||||
<linearGradient id='invoice-linearGradient-1' x1='100%' y1='10.5120544%' x2='50%' y2='89.4879456%'>
|
||||
<stop stopColor='#000000' offset='0%'></stop>
|
||||
<stop stopColor='#FFFFFF' offset='100%'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id='invoice-linearGradient-2'
|
||||
x1='64.0437835%'
|
||||
y1='46.3276743%'
|
||||
x2='37.373316%'
|
||||
y2='100%'
|
||||
>
|
||||
<stop stopColor='#EEEEEE' stopOpacity='0' offset='0%'></stop>
|
||||
<stop stopColor='#FFFFFF' offset='100%'></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g stroke='none' strokeWidth='1' fill='none' fillRule='evenodd'>
|
||||
<g transform='translate(-400.000000, -178.000000)'>
|
||||
<g transform='translate(400.000000, 178.000000)'>
|
||||
<path
|
||||
className='text-primary'
|
||||
d='M-5.68434189e-14,2.84217094e-14 L39.1816085,2.84217094e-14 L69.3453773,32.2519224 L101.428699,2.84217094e-14 L138.784583,2.84217094e-14 L138.784199,29.8015838 C137.958931,37.3510206 135.784352,42.5567762 132.260463,45.4188507 C128.736573,48.2809251 112.33867,64.5239941 83.0667527,94.1480575 L56.2750821,94.1480575 L6.71554594,44.4188507 C2.46876683,39.9813776 0.345377275,35.1089553 0.345377275,29.8015838 C0.345377275,24.4942122 0.230251516,14.560351 -5.68434189e-14,2.84217094e-14 Z'
|
||||
style={{ fill: 'currentColor' }}
|
||||
></path>
|
||||
<path
|
||||
d='M69.3453773,32.2519224 L101.428699,1.42108547e-14 L138.784583,1.42108547e-14 L138.784199,29.8015838 C137.958931,37.3510206 135.784352,42.5567762 132.260463,45.4188507 C128.736573,48.2809251 112.33867,64.5239941 83.0667527,94.1480575 L56.2750821,94.1480575 L32.8435758,70.5039241 L69.3453773,32.2519224 Z'
|
||||
fill='url(#invoice-linearGradient-1)'
|
||||
opacity='0.2'
|
||||
></path>
|
||||
<polygon
|
||||
fill='#000000'
|
||||
opacity='0.049999997'
|
||||
points='69.3922914 32.4202615 32.8435758 70.5039241 54.0490008 16.1851325'
|
||||
></polygon>
|
||||
<polygon
|
||||
fill='#000000'
|
||||
opacity='0.099999994'
|
||||
points='69.3922914 32.4202615 32.8435758 70.5039241 58.3683556 20.7402338'
|
||||
></polygon>
|
||||
<polygon
|
||||
fill='url(#invoice-linearGradient-2)'
|
||||
opacity='0.099999994'
|
||||
points='101.428699 0 83.0667527 94.1480575 130.378721 47.0740288'
|
||||
></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<h3 className='text-primary font-weight-bold ml-1'></h3>
|
||||
</div>
|
||||
<p className='mb-25'>Office 149, 450 South Brand Brooklyn</p>
|
||||
<p className='mb-25'>San Diego County, CA 91905, USA</p>
|
||||
<p className='mb-0'>+1 (123) 456 7891, +44 (876) 543 2198</p>
|
||||
</div>
|
||||
<div className='mt-md-0 mt-2'>
|
||||
<h4 className='font-weight-bold text-right mb-1'>INVOICE #3492</h4>
|
||||
<div className='invoice-date-wrapper mb-50'>
|
||||
<span className='invoice-date-title'>Date Issued:</span>
|
||||
<span className='font-weight-bold'> 25/08/2020</span>
|
||||
</div>
|
||||
<div className='invoice-date-wrapper'>
|
||||
<span className='invoice-date-title'>Due Date:</span>
|
||||
<span className='font-weight-bold'>29/08/2020</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className='my-2' />
|
||||
|
||||
<Row className='pb-2'>
|
||||
<Col sm='6'>
|
||||
<h6 className='mb-1'>Invoice To:</h6>
|
||||
<p className='mb-25'>Thomas shelby</p>
|
||||
<p className='mb-25'>Shelby Company Limited</p>
|
||||
<p className='mb-25'>Small Heath, B10 0HF, UK</p>
|
||||
<p className='mb-25'>718-986-6062</p>
|
||||
<p className='mb-0'>peakyFBlinders@gmail.com</p>
|
||||
</Col>
|
||||
<Col className='mt-sm-0 mt-2' sm='6'>
|
||||
<h6 className='mb-1'>Payment Details:</h6>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className='pr-1'>Total Due:</td>
|
||||
<td>
|
||||
<strong>$12,110.55</strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>Bank name:</td>
|
||||
<td>American Bank</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>Country:</td>
|
||||
<td>United States</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>IBAN:</td>
|
||||
<td>ETD95476213874685</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='pr-1'>SWIFT code:</td>
|
||||
<td>BR91905</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Table className='mt-2 mb-0' responsive>
|
||||
<thead>
|
||||
<tr>
|
||||
<th className='py-1 pl-4'>Task description</th>
|
||||
<th className='py-1'>Rate</th>
|
||||
<th className='py-1'>Hours</th>
|
||||
<th className='py-1'>Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className='py-1 pl-4'>
|
||||
<p className='font-weight-semibold mb-25'>Native App Development</p>
|
||||
<p className='text-muted text-nowrap'>
|
||||
Developed a full stack native app using React Native, Bootstrap & Python
|
||||
</p>
|
||||
</td>
|
||||
<td className='py-1'>
|
||||
<strong>$60.00</strong>
|
||||
</td>
|
||||
<td className='py-1'>
|
||||
<strong>30</strong>
|
||||
</td>
|
||||
<td className='py-1'>
|
||||
<strong>$1,800.00</strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className='border-bottom'>
|
||||
<td className='py-1 pl-4'>
|
||||
<p className='font-weight-semibold mb-25'>Ui Kit Design</p>
|
||||
<p className='text-muted text-nowrap'>Designed a UI kit for native app using Sketch, Figma & Adobe XD</p>
|
||||
</td>
|
||||
<td className='py-1'>
|
||||
<strong>$60.00</strong>
|
||||
</td>
|
||||
<td className='py-1'>
|
||||
<strong>20</strong>
|
||||
</td>
|
||||
<td className='py-1'>
|
||||
<strong>$1200.00</strong>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</Table>
|
||||
|
||||
<Row className='invoice-sales-total-wrapper mt-3'>
|
||||
<Col className='mt-md-0 mt-3' md='6' order={{ md: 1, lg: 2 }}>
|
||||
<p className='mb-0'>
|
||||
<span className='font-weight-bold'>Salesperson:</span> <span className='ml-75'>Alfie Solomons</span>
|
||||
</p>
|
||||
</Col>
|
||||
<Col className='d-flex justify-content-end' md='6' order={{ md: 2, lg: 1 }}>
|
||||
<div className='invoice-total-wrapper'>
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Subtotal:</p>
|
||||
<p className='invoice-total-amount'>$1800</p>
|
||||
</div>
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Discount:</p>
|
||||
<p className='invoice-total-amount'>$28</p>
|
||||
</div>
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Tax:</p>
|
||||
<p className='invoice-total-amount'>21%</p>
|
||||
</div>
|
||||
<hr className='my-50' />
|
||||
<div className='invoice-total-item'>
|
||||
<p className='invoice-total-title'>Total:</p>
|
||||
<p className='invoice-total-amount'>$1690</p>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<hr className='my-2' />
|
||||
|
||||
<Row>
|
||||
<Col sm='12'>
|
||||
<span className='font-weight-bold'>Note:</span>
|
||||
<span>
|
||||
It was a pleasure working with you and your team. We hope you will keep us in mind for future freelance
|
||||
projects. Thank You!
|
||||
</span>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Print
|
@ -1,78 +0,0 @@
|
||||
// ** React Imports
|
||||
import { useState } from 'react'
|
||||
|
||||
// ** Third Party Components
|
||||
import Flatpickr from 'react-flatpickr'
|
||||
import { Form, FormGroup, Input, Label, Button } from 'reactstrap'
|
||||
|
||||
// ** Custom Components
|
||||
import Sidebar from '@components/sidebar'
|
||||
|
||||
// ** Styles
|
||||
import '@styles/react/libs/flatpickr/flatpickr.scss'
|
||||
import '@styles/base/pages/app-invoice.scss'
|
||||
|
||||
const SidebarAddPayment = ({ open, toggleSidebar }) => {
|
||||
// ** States
|
||||
const [picker, setPicker] = useState(new Date())
|
||||
|
||||
return (
|
||||
<Sidebar
|
||||
size='lg'
|
||||
open={open}
|
||||
title='Add Payment'
|
||||
headerClassName='mb-1'
|
||||
contentClassName='p-0'
|
||||
toggleSidebar={toggleSidebar}
|
||||
>
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<Input id='balance' defaultValue='Invoice Balance: 5000.00' disabled />
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='amount' className='form-label'>
|
||||
Payment Amount
|
||||
</Label>
|
||||
<Input type='number' id='amount' placeholder='$1000' />
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='payment-amount' className='form-label'>
|
||||
Payment Date
|
||||
</Label>
|
||||
<Flatpickr id='payment-amount' value={picker} onChange={date => setPicker(date)} className='form-control' />
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='payment-method' className='form-label'>
|
||||
Payment Method
|
||||
</Label>
|
||||
<Input type='select' id='payment-method' defaultValue=''>
|
||||
<option value='' disabled>
|
||||
Select payment method
|
||||
</option>
|
||||
<option value='Cash'>Cash</option>
|
||||
<option value='Bank Transfer'>Bank Transfer</option>
|
||||
<option value='Debit'>Debit</option>
|
||||
<option value='Credit'>Credit</option>
|
||||
<option value='Paypal'>Paypal</option>
|
||||
</Input>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='payment-note' className='form-label'>
|
||||
Internal Payment Note
|
||||
</Label>
|
||||
<Input type='textarea' rows='5' id='payment-note' placeholder='Internal Payment Note' />
|
||||
</FormGroup>
|
||||
<FormGroup className='d-flex flex-wrap mb-0'>
|
||||
<Button className='mr-1' color='primary' onClick={toggleSidebar}>
|
||||
Send
|
||||
</Button>
|
||||
<Button color='secondary' outline onClick={toggleSidebar}>
|
||||
Cancel
|
||||
</Button>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
</Sidebar>
|
||||
)
|
||||
}
|
||||
|
||||
export default SidebarAddPayment
|
@ -1,79 +0,0 @@
|
||||
// ** Custom Components
|
||||
import Sidebar from '@components/sidebar'
|
||||
|
||||
// ** Third Party Components
|
||||
import { Link } from 'react-feather'
|
||||
import { Form, FormGroup, Input, Label, Badge, Button } from 'reactstrap'
|
||||
|
||||
const SidebarSendInvoice = ({ open, toggleSidebar }) => {
|
||||
return (
|
||||
<Sidebar
|
||||
size='lg'
|
||||
open={open}
|
||||
title='Send Invoice'
|
||||
headerClassName='mb-1'
|
||||
contentClassName='p-0'
|
||||
bodyClassName='pb-sm-0 pb-3'
|
||||
toggleSidebar={toggleSidebar}
|
||||
>
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<Label for='invoice-from' className='form-label'>
|
||||
From
|
||||
</Label>
|
||||
<Input id='invoice-from' defaultValue='shelbyComapny@email.com' placeholder='company@email.com' />
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='invoice-to' className='form-label'>
|
||||
To
|
||||
</Label>
|
||||
<Input id='invoice-to' defaultValue='qConsolidated@email.com' placeholder='company@email.com' />
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='invoice-subject' className='form-label'>
|
||||
Subject
|
||||
</Label>
|
||||
<Input
|
||||
id='invoice-subject'
|
||||
defaultValue='Invoice of purchased Admin Templates'
|
||||
placeholder='Invoice regarding goods'
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='invoice-message' className='form-label'>
|
||||
Message
|
||||
</Label>
|
||||
<Input
|
||||
type='textarea'
|
||||
cols='3'
|
||||
rows='11'
|
||||
id='invoice-message'
|
||||
defaultValue={`Dear Queen Consolidated,
|
||||
|
||||
Thank you for your business, always a pleasure to work with you!
|
||||
|
||||
We have generated a new invoice in the amount of $95.59
|
||||
|
||||
We would appreciate payment of this invoice by 05/11/2019`}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Badge color='light-primary'>
|
||||
<Link className='mr-50' size={14} />
|
||||
<span className='align-middle'>Invoice Attached</span>
|
||||
</Badge>
|
||||
</FormGroup>
|
||||
<FormGroup className='d-flex flex-wrap mt-2'>
|
||||
<Button className='mr-1' color='primary' onClick={toggleSidebar}>
|
||||
Send
|
||||
</Button>
|
||||
<Button color='secondary' outline onClick={toggleSidebar}>
|
||||
Cancel
|
||||
</Button>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
</Sidebar>
|
||||
)
|
||||
}
|
||||
|
||||
export default SidebarSendInvoice
|
@ -1,30 +0,0 @@
|
||||
import axios from 'axios'
|
||||
|
||||
// ** Get data
|
||||
export const getData = params => {
|
||||
return dispatch => {
|
||||
axios.get('/apps/invoice/invoices', params).then(response => {
|
||||
dispatch({
|
||||
type: 'GET_DATA',
|
||||
allData: response.data.allData,
|
||||
data: response.data.invoices,
|
||||
totalPages: response.data.total,
|
||||
params
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ** Delete Invoice
|
||||
export const deleteInvoice = id => {
|
||||
return (dispatch, getStore) => {
|
||||
axios
|
||||
.delete('/apps/invoice/delete', { id })
|
||||
.then(response => {
|
||||
dispatch({
|
||||
type: 'DELETE_INVOICE'
|
||||
})
|
||||
})
|
||||
.then(() => dispatch(getData(getStore().invoice.params)))
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
const initialState = {
|
||||
data: [],
|
||||
total: 1,
|
||||
params: {},
|
||||
allData: []
|
||||
}
|
||||
|
||||
const invoiceReducer = (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
case 'GET_DATA':
|
||||
return {
|
||||
...state,
|
||||
allData: action.allData,
|
||||
data: action.data,
|
||||
total: action.totalPages,
|
||||
params: action.params
|
||||
}
|
||||
case 'DELETE_INVOICE':
|
||||
return { ...state }
|
||||
default:
|
||||
return { ...state }
|
||||
}
|
||||
}
|
||||
export default invoiceReducer
|
@ -13,7 +13,6 @@ import { Row, Col, Alert } from 'reactstrap'
|
||||
import PlanCard from './PlanCard'
|
||||
import UserInfoCard from './UserInfoCard'
|
||||
import UserTimeline from './UserTimeline'
|
||||
import InvoiceList from '../../invoice/list'
|
||||
import PermissionsTable from './PermissionsTable'
|
||||
|
||||
// ** Styles
|
||||
|
@ -1,33 +0,0 @@
|
||||
import { useContext } from 'react'
|
||||
import { AbilityContext } from '@src/utility/context/Can'
|
||||
import { Row, Col, Card, CardBody, CardTitle, CardText } from 'reactstrap'
|
||||
|
||||
const AccessControl = () => {
|
||||
const ability = useContext(AbilityContext)
|
||||
return (
|
||||
<Row>
|
||||
<Col md='6' sm='12'>
|
||||
<Card>
|
||||
<CardBody>
|
||||
<CardTitle tag='h4'>Common</CardTitle>
|
||||
<CardText>No ability is required to view this card</CardText>
|
||||
<CardText className='text-primary'>This card is visible to 'user' and 'admin' both</CardText>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
{ability.can('read', 'Analytics') ? (
|
||||
<Col md='6' sm='12'>
|
||||
<Card>
|
||||
<CardBody>
|
||||
<CardTitle tag='h4'>Analytics</CardTitle>
|
||||
<CardText>User with 'Analytics' subject's 'Read' ability can view this card</CardText>
|
||||
<CardText className='text-danger'>This card is visible to 'admin' only</CardText>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
) : null}
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default AccessControl
|
@ -1,86 +0,0 @@
|
||||
import { Fragment } from 'react'
|
||||
import Avatar from '@components/avatar'
|
||||
import { toast } from 'react-toastify'
|
||||
import { Check } from 'react-feather'
|
||||
import { Card, CardHeader, CardBody, CardTitle, Button } from 'reactstrap'
|
||||
import { Menu, Item, useContextMenu, animation } from 'react-contexify'
|
||||
|
||||
const ToastContent = ({ text }) => (
|
||||
<Fragment>
|
||||
<div className='toastify-header pb-0'>
|
||||
<div className='title-wrapper'>
|
||||
<Avatar size='sm' color='success' icon={<Check />} />
|
||||
<h6 className='toast-title'>Clicked {text}</h6>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
|
||||
const ContextMenuAnimations = () => {
|
||||
const { show: showFade } = useContextMenu({
|
||||
id: 'fade'
|
||||
})
|
||||
const { show: showFlip } = useContextMenu({
|
||||
id: 'flip'
|
||||
})
|
||||
const { show: showSlide } = useContextMenu({
|
||||
id: 'pop'
|
||||
})
|
||||
|
||||
const handleClick = text => {
|
||||
toast.success(<ToastContent text={text} />, { hideProgressBar: true, closeButton: false })
|
||||
}
|
||||
|
||||
const FadeMenu = () => {
|
||||
return (
|
||||
<Menu id='fade' animation={animation.fade}>
|
||||
<Item onClick={() => handleClick('Option 1')}>Option 1</Item>
|
||||
<Item onClick={() => handleClick('Option 2')}>Option 2</Item>
|
||||
</Menu>
|
||||
)
|
||||
}
|
||||
const FlipMenu = () => {
|
||||
return (
|
||||
<Menu id='flip' animation={animation.flip}>
|
||||
<Item onClick={() => handleClick('Option 1')}>Option 1</Item>
|
||||
<Item onClick={() => handleClick('Option 2')}>Option 2</Item>
|
||||
</Menu>
|
||||
)
|
||||
}
|
||||
const SlideMenu = () => {
|
||||
return (
|
||||
<Menu id='pop' animation={animation.slide}>
|
||||
<Item onClick={() => handleClick('Option 1')}>Option 1</Item>
|
||||
<Item onClick={() => handleClick('Option 2')}>Option 2</Item>
|
||||
</Menu>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Animations</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<div className='demo-inline-spacing'>
|
||||
<Button color='primary' onContextMenu={showFade} outline>
|
||||
Fade
|
||||
</Button>
|
||||
|
||||
<Button color='primary' onContextMenu={showFlip} outline>
|
||||
Flip
|
||||
</Button>
|
||||
|
||||
<Button color='primary' onContextMenu={showSlide} outline>
|
||||
Slide
|
||||
</Button>
|
||||
</div>
|
||||
<FadeMenu />
|
||||
<FlipMenu />
|
||||
<SlideMenu />
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default ContextMenuAnimations
|
@ -1,46 +0,0 @@
|
||||
import { Fragment } from 'react'
|
||||
import Avatar from '@components/avatar'
|
||||
import { toast } from 'react-toastify'
|
||||
import { Check } from 'react-feather'
|
||||
import { Menu, Item, useContextMenu } from 'react-contexify'
|
||||
import { Card, CardHeader, CardBody, CardTitle, Button } from 'reactstrap'
|
||||
|
||||
const ToastContent = ({ text }) => (
|
||||
<Fragment>
|
||||
<div className='toastify-header pb-0'>
|
||||
<div className='title-wrapper'>
|
||||
<Avatar size='sm' color='success' icon={<Check />} />
|
||||
<h6 className='toast-title'>Clicked {text}</h6>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
|
||||
const ContextMenuBasic = () => {
|
||||
const { show } = useContextMenu({
|
||||
id: 'menu_id'
|
||||
})
|
||||
|
||||
const handleClick = text => {
|
||||
toast.success(<ToastContent text={text} />, { hideProgressBar: true, closeButton: false })
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Basic Context Menu</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Button color='primary' onContextMenu={show} outline>
|
||||
Right Click On Me
|
||||
</Button>
|
||||
<Menu id='menu_id'>
|
||||
<Item onClick={() => handleClick('Option 1')}>Item 1</Item>
|
||||
<Item onClick={() => handleClick('Option 2')}>Item 2</Item>
|
||||
</Menu>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default ContextMenuBasic
|
@ -1,46 +0,0 @@
|
||||
import { Fragment } from 'react'
|
||||
import Avatar from '@components/avatar'
|
||||
import { toast } from 'react-toastify'
|
||||
import { Check } from 'react-feather'
|
||||
import { Card, CardHeader, CardBody, CardTitle, Button } from 'reactstrap'
|
||||
import { Menu, Item, useContextMenu } from 'react-contexify'
|
||||
|
||||
const ToastContent = ({ text }) => (
|
||||
<Fragment>
|
||||
<div className='toastify-header pb-0'>
|
||||
<div className='title-wrapper'>
|
||||
<Avatar size='sm' color='success' icon={<Check />} />
|
||||
<h6 className='toast-title'>Clicked {text}</h6>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
|
||||
const ContextMenuDoubleClick = () => {
|
||||
const { show } = useContextMenu({
|
||||
id: 'menu_double'
|
||||
})
|
||||
|
||||
const handleClick = text => {
|
||||
toast.success(<ToastContent text={text} />, { hideProgressBar: true, closeButton: false })
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Double Click</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Button color='primary' onDoubleClick={show} outline>
|
||||
Double Click On Me
|
||||
</Button>
|
||||
<Menu id='menu_double'>
|
||||
<Item onClick={() => handleClick('Option 1')}>Option 1</Item>
|
||||
<Item onClick={() => handleClick('Option 2')}>Option 2</Item>
|
||||
</Menu>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default ContextMenuDoubleClick
|
@ -1,46 +0,0 @@
|
||||
import { Fragment } from 'react'
|
||||
import Avatar from '@components/avatar'
|
||||
import { toast } from 'react-toastify'
|
||||
import { Check } from 'react-feather'
|
||||
import { Card, CardHeader, CardBody, CardTitle, Button } from 'reactstrap'
|
||||
import { Menu, Item, useContextMenu } from 'react-contexify'
|
||||
|
||||
const ToastContent = ({ text }) => (
|
||||
<Fragment>
|
||||
<div className='toastify-header pb-0'>
|
||||
<div className='title-wrapper'>
|
||||
<Avatar size='sm' color='success' icon={<Check />} />
|
||||
<h6 className='toast-title'>Clicked {text}</h6>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
|
||||
const ContextMenuLeftClick = () => {
|
||||
const { show } = useContextMenu({
|
||||
id: 'menu_left'
|
||||
})
|
||||
|
||||
const handleClick = text => {
|
||||
toast.success(<ToastContent text={text} />, { hideProgressBar: true, closeButton: false })
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Left Click</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Button color='primary' onClick={show} outline>
|
||||
Left Click On Me
|
||||
</Button>
|
||||
<Menu id='menu_left'>
|
||||
<Item onClick={() => handleClick('Option 1')}>Option 1</Item>
|
||||
<Item onClick={() => handleClick('Option 2')}>Option 2</Item>
|
||||
</Menu>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default ContextMenuLeftClick
|
@ -1,55 +0,0 @@
|
||||
import { Fragment } from 'react'
|
||||
import Avatar from '@components/avatar'
|
||||
import { toast } from 'react-toastify'
|
||||
import { Check } from 'react-feather'
|
||||
import { Menu, Item, Submenu, useContextMenu } from 'react-contexify'
|
||||
import { Card, CardHeader, CardBody, CardTitle, Button } from 'reactstrap'
|
||||
|
||||
const ToastContent = ({ text }) => (
|
||||
<Fragment>
|
||||
<div className='toastify-header pb-0'>
|
||||
<div className='title-wrapper'>
|
||||
<Avatar size='sm' color='success' icon={<Check />} />
|
||||
<h6 className='toast-title'>Clicked {text}</h6>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
|
||||
const ContextSubMenu = () => {
|
||||
const { show } = useContextMenu({
|
||||
id: 'submenu_id'
|
||||
})
|
||||
|
||||
const handleClick = text => {
|
||||
toast.success(<ToastContent text={text} />, { hideProgressBar: true, closeButton: false })
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Sub Menu</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Button color='primary' onContextMenu={show} outline>
|
||||
Submenu
|
||||
</Button>
|
||||
<Menu id='submenu_id'>
|
||||
<Item onClick={() => handleClick('Option 1')}>Option 1</Item>
|
||||
<Item onClick={() => handleClick('Option 2')}>Option 2</Item>
|
||||
<Item disabled>Option 3</Item>
|
||||
<Submenu label='Submenu'>
|
||||
<Item onClick={() => handleClick('Foo Bar')}>Foo Bar</Item>
|
||||
<Submenu label='Submenu'>
|
||||
<Item onClick={() => handleClick('Echo')}>Echo</Item>
|
||||
<Item onClick={() => handleClick('Foxtrot')}>Foxtrot</Item>
|
||||
<Item onClick={() => handleClick('Golf')}>Golf</Item>
|
||||
</Submenu>
|
||||
</Submenu>
|
||||
</Menu>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default ContextSubMenu
|
@ -1,42 +0,0 @@
|
||||
import { Fragment } from 'react'
|
||||
import ExtensionsHeader from '@components/extensions-header'
|
||||
import { Row, Col } from 'reactstrap'
|
||||
import ContextMenuBasic from './ContextMenuBasic'
|
||||
import ContextMenuLeftClick from './ContextMenuLeftClick'
|
||||
import ContextMenuDoubleClick from './ContextMenuDoubleClick'
|
||||
import ContextSubMenu from './ContextSubmenu'
|
||||
import ContextMenuAnimation from './ContextMenuAnimation'
|
||||
|
||||
import 'react-contexify/dist/ReactContexify.min.css'
|
||||
import '@styles/react/libs/context-menu/context-menu.scss'
|
||||
|
||||
const Contexify = () => {
|
||||
return (
|
||||
<Fragment>
|
||||
<ExtensionsHeader
|
||||
title='React Contexify'
|
||||
subTitle='Adds a context menu to your react app with ease'
|
||||
link='https://github.com/fkhadra/react-contexify'
|
||||
/>
|
||||
<Row>
|
||||
<Col sm='12'>
|
||||
<ContextMenuBasic />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<ContextSubMenu />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<ContextMenuLeftClick />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<ContextMenuDoubleClick />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<ContextMenuAnimation />
|
||||
</Col>
|
||||
</Row>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default Contexify
|
@ -1,74 +0,0 @@
|
||||
import { Fragment, useState } from 'react'
|
||||
import { toast } from 'react-toastify'
|
||||
import { Check } from 'react-feather'
|
||||
import Avatar from '@components/avatar'
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard'
|
||||
import ExtensionsHeader from '@components/extensions-header'
|
||||
import { Row, Col, Card, CardHeader, CardTitle, CardBody, Button, Input } from 'reactstrap'
|
||||
|
||||
const ToastSuccess = () => (
|
||||
<Fragment>
|
||||
<div className='toastify-header pb-0'>
|
||||
<div className='title-wrapper'>
|
||||
<Avatar size='sm' color='success' icon={<Check />} />
|
||||
<h6 className='toast-title'>Copied To Clipboard !</h6>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
|
||||
/*eslint-disable */
|
||||
const Clipboard = () => {
|
||||
const [value, setValue] = useState('Copy Me!')
|
||||
const [copied, setCopied] = useState(false)
|
||||
/*eslint-enable */
|
||||
|
||||
const handleCopy = ({ target: { value } }) => {
|
||||
setValue(value)
|
||||
setCopied(false)
|
||||
}
|
||||
|
||||
const onCopy = () => {
|
||||
setCopied(true)
|
||||
toast.success(<ToastSuccess />, {
|
||||
autoClose: 3000,
|
||||
hideProgressBar: true,
|
||||
closeButton: false
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<ExtensionsHeader
|
||||
title='React Copy To Clipboard'
|
||||
subTitle='Copy to clipboard React component'
|
||||
link='https://github.com/nkbt/react-copy-to-clipboard'
|
||||
/>
|
||||
<Row>
|
||||
<Col sm='12'>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Clipboard</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Row>
|
||||
<Col xl='3' md='4' sm='6' className='pr-sm-0 mb-md-0 mb-1'>
|
||||
<Input value={value} onChange={handleCopy} />
|
||||
</Col>
|
||||
<Col md='2' sm='12'>
|
||||
<CopyToClipboard onCopy={onCopy} text={value}>
|
||||
<Button.Ripple color='primary' outline>
|
||||
Copy!
|
||||
</Button.Ripple>
|
||||
</CopyToClipboard>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default Clipboard
|
@ -1,53 +0,0 @@
|
||||
import { useState } from 'react'
|
||||
import { ReactSortable } from 'react-sortablejs'
|
||||
import { Card, CardHeader, CardBody, CardTitle, CardText, Col } from 'reactstrap'
|
||||
|
||||
const dragItems = [
|
||||
{
|
||||
id: '1',
|
||||
title: 'Draggable Card 1',
|
||||
content:
|
||||
'Jelly beans sugar plum cheesecake cookie oat cake soufflé.Tootsie roll bonbon liquorice tiramisu pie powder.Donut sweet roll marzipan pastry cookie cake tootsie roll oat cake cookie.'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Draggable Card 2',
|
||||
content:
|
||||
'Jelly beans sugar plum cheesecake cookie oat cake soufflé.Tootsie roll bonbon liquorice tiramisu pie powder.Donut sweet roll marzipan pastry cookie cake tootsie roll oat cake cookie.'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
title: 'Draggable Card 3',
|
||||
content:
|
||||
'Jelly beans sugar plum cheesecake cookie oat cake soufflé.Tootsie roll bonbon liquorice tiramisu pie powder.Donut sweet roll marzipan pastry cookie cake tootsie roll oat cake cookie.'
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
title: 'Draggable Card 4',
|
||||
content:
|
||||
'Jelly beans sugar plum cheesecake cookie oat cake soufflé.Tootsie roll bonbon liquorice tiramisu pie powder.Donut sweet roll marzipan pastry cookie cake tootsie roll oat cake cookie.'
|
||||
}
|
||||
]
|
||||
|
||||
const DndCards = () => {
|
||||
const [cardsArr, setCardsArr] = useState(dragItems)
|
||||
|
||||
return (
|
||||
<ReactSortable className='row sortable-row' list={cardsArr} setList={setCardsArr}>
|
||||
{cardsArr.map(item => (
|
||||
<Col className='draggable' xl='3' md='6' sm='12' key={item.id}>
|
||||
<Card className={`draggable-cards ${item.id !== 4 ? 'mr-1' : null}`}>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>{item.title}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<CardText>{item.content}</CardText>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
))}
|
||||
</ReactSortable>
|
||||
)
|
||||
}
|
||||
|
||||
export default DndCards
|
@ -1,112 +0,0 @@
|
||||
import { useState } from 'react'
|
||||
import { ReactSortable } from 'react-sortablejs'
|
||||
import { Card, CardHeader, CardTitle, CardBody, CardText, Row, Col, Badge } from 'reactstrap'
|
||||
|
||||
const DndClone = () => {
|
||||
const source1 = [
|
||||
{
|
||||
text: 'Youtube',
|
||||
color: 'light-secondary'
|
||||
},
|
||||
{
|
||||
text: 'Facebook',
|
||||
color: 'light-primary'
|
||||
},
|
||||
{
|
||||
text: 'Google',
|
||||
color: 'light-success'
|
||||
},
|
||||
{
|
||||
text: 'Instagram',
|
||||
color: 'light-danger'
|
||||
},
|
||||
{
|
||||
text: 'Twitter',
|
||||
color: 'light-info'
|
||||
},
|
||||
{
|
||||
text: 'Discord',
|
||||
color: 'light-warning'
|
||||
}
|
||||
]
|
||||
const source2 = [
|
||||
{
|
||||
text: 'Github',
|
||||
color: 'light-secondary'
|
||||
},
|
||||
{
|
||||
text: 'Gitlab',
|
||||
color: 'light-primary'
|
||||
},
|
||||
{
|
||||
text: 'Slack',
|
||||
color: 'light-success'
|
||||
},
|
||||
{
|
||||
text: 'Pinterest',
|
||||
color: 'light-danger'
|
||||
},
|
||||
{
|
||||
text: 'Tinder',
|
||||
color: 'light-info'
|
||||
},
|
||||
{
|
||||
text: 'Amazon',
|
||||
color: 'light-warning'
|
||||
}
|
||||
]
|
||||
|
||||
const [list, setList] = useState(source1)
|
||||
const [list2, setList2] = useState(source2)
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Clone List</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<CardText>
|
||||
Add <code>pull:clone</code> with your group prop to clone items.
|
||||
</CardText>
|
||||
<Row>
|
||||
<Col md='6' sm='12'>
|
||||
<h4 className='my-1'>Badge Source 1</h4>
|
||||
<ReactSortable
|
||||
className='demo-inline-spacing sortable'
|
||||
group={{ name: 'shared-badge-group', pull: 'clone' }}
|
||||
list={list}
|
||||
setList={setList}
|
||||
>
|
||||
{list.map(item => {
|
||||
return (
|
||||
<Badge className='draggable' key={item.text} color={item.color} pill>
|
||||
{item.text}
|
||||
</Badge>
|
||||
)
|
||||
})}
|
||||
</ReactSortable>
|
||||
</Col>
|
||||
<Col md='6' sm='12'>
|
||||
<h4 className='my-1'>Badge Source 2</h4>
|
||||
<ReactSortable
|
||||
className='demo-inline-spacing sortable'
|
||||
group={{ name: 'shared-badge-group', pull: 'clone' }}
|
||||
list={list2}
|
||||
setList={setList2}
|
||||
>
|
||||
{list2.map(item => {
|
||||
return (
|
||||
<Badge className='draggable' key={item.text} color={item.color} pill>
|
||||
{item.text}
|
||||
</Badge>
|
||||
)
|
||||
})}
|
||||
</ReactSortable>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default DndClone
|
@ -1,112 +0,0 @@
|
||||
import { useState } from 'react'
|
||||
import { ReactSortable } from 'react-sortablejs'
|
||||
import { Card, CardHeader, CardTitle, CardBody, CardText, Row, Col, ListGroupItem } from 'reactstrap'
|
||||
|
||||
const array = {
|
||||
list1: [
|
||||
{
|
||||
id: '1',
|
||||
content: 'Cras justo odio'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
content: 'Dapibus ac facilisis in'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
content: 'Morbi leo risus'
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
content: 'Porta ac consectetur ac'
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
content: 'Vestibulum at eros'
|
||||
}
|
||||
],
|
||||
list2: [
|
||||
{
|
||||
id: '6',
|
||||
content: 'Cras justo odio'
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
content: 'Dapibus ac facilisis in'
|
||||
},
|
||||
{
|
||||
id: '8',
|
||||
content: 'Morbi leo risus'
|
||||
},
|
||||
{
|
||||
id: '9',
|
||||
content: 'Porta ac consectetur ac'
|
||||
},
|
||||
{
|
||||
id: '10',
|
||||
content: 'Vestibulum at eros'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const DndMultiple = () => {
|
||||
const [listArr1, setListArr1] = useState(array.list1)
|
||||
const [listArr2, setListArr2] = useState(array.list2)
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Drag And Drop With Handle</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<CardText>
|
||||
Add handle to your items using <code>handle</code> prop.
|
||||
</CardText>
|
||||
<Row id='dd-with-handle'>
|
||||
<Col md='6' sm='12'>
|
||||
<h4 className='my-1'>List One</h4>
|
||||
<ReactSortable
|
||||
tag='ul'
|
||||
className='list-group sortable'
|
||||
group='shared-handle-group'
|
||||
handle='.handle'
|
||||
list={listArr1}
|
||||
setList={setListArr1}
|
||||
>
|
||||
{listArr1.map(item => {
|
||||
return (
|
||||
<ListGroupItem className='draggable' key={item.id}>
|
||||
<span className='handle'>+</span>
|
||||
{item.content}
|
||||
</ListGroupItem>
|
||||
)
|
||||
})}
|
||||
</ReactSortable>
|
||||
</Col>
|
||||
<Col md='6' sm='12'>
|
||||
<h4 className='my-1'>People Group 2</h4>
|
||||
<ReactSortable
|
||||
tag='ul'
|
||||
className='list-group sortable'
|
||||
group='shared-handle-group'
|
||||
handle='.handle'
|
||||
list={listArr2}
|
||||
setList={setListArr2}
|
||||
>
|
||||
{listArr2.map(item => {
|
||||
return (
|
||||
<ListGroupItem className='draggable' key={item.id}>
|
||||
<span className='handle'>+</span>
|
||||
{item.content}
|
||||
</ListGroupItem>
|
||||
)
|
||||
})}
|
||||
</ReactSortable>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default DndMultiple
|
@ -1,83 +0,0 @@
|
||||
import { useState } from 'react'
|
||||
import { ReactSortable } from 'react-sortablejs'
|
||||
import img1 from '@src/assets/images/portrait/small/avatar-s-12.jpg'
|
||||
import img2 from '@src/assets/images/portrait/small/avatar-s-1.jpg'
|
||||
import img3 from '@src/assets/images/portrait/small/avatar-s-2.jpg'
|
||||
import img4 from '@src/assets/images/portrait/small/avatar-s-3.jpg'
|
||||
import img5 from '@src/assets/images/portrait/small/avatar-s-4.jpg'
|
||||
import { Card, CardHeader, CardTitle, CardBody, CardText, ListGroupItem, Media } from 'reactstrap'
|
||||
|
||||
const listItems = [
|
||||
{
|
||||
id: '1',
|
||||
img: img1,
|
||||
name: 'Mary S. Navarre',
|
||||
content: 'Chupa chups tiramisu apple pie biscuit sweet roll bonbon macaroon toffee icing.'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
img: img2,
|
||||
name: 'Samuel M. Ellis',
|
||||
content: 'Toffee powder marzipan tiramisu. Cake cake dessert danish.'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
img: img3,
|
||||
name: 'Sandra C. Toney',
|
||||
content: 'Sugar plum fruitcake gummies marzipan liquorice tiramisu. Pastry liquorice chupa chupsake.'
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
img: img4,
|
||||
name: 'Cleveland C. Goins',
|
||||
content: 'Toffee powder marzipan tiramisu. Cake cake dessert danish.'
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
img: img5,
|
||||
name: 'Linda M. English',
|
||||
content: 'Chupa chups tiramisu apple pie biscuit sweet roll bonbon macaroon toffee icing.'
|
||||
}
|
||||
]
|
||||
|
||||
const DndListGroup = () => {
|
||||
const [listArr, setListArr] = useState(listItems)
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Basic List Group Sortable</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<CardText>
|
||||
The most basic list group is simply an unordered list with list items, and the proper classes.
|
||||
</CardText>
|
||||
<ReactSortable tag='ul' className='list-group' list={listArr} setList={setListArr}>
|
||||
{listArr.map(item => {
|
||||
return (
|
||||
<ListGroupItem key={item.name}>
|
||||
<Media>
|
||||
<Media left tag='div'>
|
||||
<Media
|
||||
object
|
||||
src={item.img}
|
||||
className='rounded-circle mr-2'
|
||||
alt='Generic placeholder image'
|
||||
height='50'
|
||||
width='50'
|
||||
/>
|
||||
</Media>
|
||||
<Media body>
|
||||
<h5 className='mt-0'>{item.name}</h5>
|
||||
{item.content}
|
||||
</Media>
|
||||
</Media>
|
||||
</ListGroupItem>
|
||||
)
|
||||
})}
|
||||
</ReactSortable>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default DndListGroup
|
@ -1,173 +0,0 @@
|
||||
import { useState } from 'react'
|
||||
import img1 from '@src/assets/images/portrait/small/avatar-s-12.jpg'
|
||||
import img2 from '@src/assets/images/portrait/small/avatar-s-1.jpg'
|
||||
import img3 from '@src/assets/images/portrait/small/avatar-s-2.jpg'
|
||||
import img4 from '@src/assets/images/portrait/small/avatar-s-3.jpg'
|
||||
import img5 from '@src/assets/images/portrait/small/avatar-s-4.jpg'
|
||||
import img6 from '@src/assets/images/portrait/small/avatar-s-5.jpg'
|
||||
import img7 from '@src/assets/images/portrait/small/avatar-s-6.jpg'
|
||||
import img8 from '@src/assets/images/portrait/small/avatar-s-7.jpg'
|
||||
import img9 from '@src/assets/images/portrait/small/avatar-s-8.jpg'
|
||||
import img10 from '@src/assets/images/portrait/small/avatar-s-9.jpg'
|
||||
import { ReactSortable, Sortable, MultiDrag } from 'react-sortablejs'
|
||||
import { Card, CardHeader, CardTitle, CardBody, CardText, Row, Col, ListGroupItem, Media } from 'reactstrap'
|
||||
|
||||
const array = {
|
||||
list1: [
|
||||
{
|
||||
id: '1',
|
||||
img: img1,
|
||||
name: 'Mary S. Navarre',
|
||||
content: 'Chupa chups tiramisu apple pie biscuit sweet roll bonbon macaroon toffee icing.'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
img: img2,
|
||||
name: 'Samuel M. Ellis',
|
||||
content: 'Toffee powder marzipan tiramisu. Cake cake dessert danish.'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
img: img3,
|
||||
name: 'Sandra C. Toney',
|
||||
content: 'Sugar plum fruitcake gummies marzipan liquorice tiramisu. Pastry liquorice chupa.'
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
img: img4,
|
||||
name: 'Cleveland C. Goins',
|
||||
content: 'Toffee powder marzipan tiramisu. Cake cake dessert danish.'
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
img: img5,
|
||||
name: 'Linda M. English',
|
||||
content: 'Chupa chups tiramisu apple pie biscuit sweet roll bonbon macaroon toffee icing.'
|
||||
}
|
||||
],
|
||||
list2: [
|
||||
{
|
||||
id: '6',
|
||||
img: img6,
|
||||
name: 'Alexandria I. Smelser',
|
||||
content: 'Toffee powder marzipan tiramisu. Cake cake dessert danish.'
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
img: img7,
|
||||
name: 'Oscar N. Pool',
|
||||
content: 'Sugar plum fruitcake gummies marzipan liquorice tiramisu. Pastry liquorice chupsake.'
|
||||
},
|
||||
{
|
||||
id: '8',
|
||||
img: img8,
|
||||
name: 'Kathy A. Alvarado',
|
||||
content: 'Chupa chups tiramisu apple pie biscuit sweet roll bonbon macaroon toffee icing.'
|
||||
},
|
||||
{
|
||||
id: '9',
|
||||
img: img9,
|
||||
name: 'James E. White',
|
||||
content: 'Toffee powder marzipan tiramisu. Cake cake dessert danish.'
|
||||
},
|
||||
{
|
||||
id: '10',
|
||||
img: img10,
|
||||
name: 'Roberta R. Babin',
|
||||
content: 'Chupa chups tiramisu apple pie biscuit sweet roll bonbon macaroon toffee icing.'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// Sortable.mount(new MultiDrag())
|
||||
const DndMultiDrag = () => {
|
||||
const [listArr1, setListArr1] = useState(array.list1)
|
||||
const [listArr2, setListArr2] = useState(array.list2)
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Multiple Drag</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<CardText>
|
||||
Use <code>MultiDrag</code> prop to create a multiple drag list.
|
||||
</CardText>
|
||||
<CardText>
|
||||
Use <code>CTRL</code> key to select multiple items.
|
||||
</CardText>
|
||||
<Row>
|
||||
<Col md='6' sm='12'>
|
||||
<h4 className='my-1'>People Group 1</h4>
|
||||
<ReactSortable
|
||||
tag='ul'
|
||||
multiDrag
|
||||
className='list-group list-group-flush sortable'
|
||||
group='shared-multi-drag-group'
|
||||
list={listArr1}
|
||||
setList={setListArr1}
|
||||
>
|
||||
{listArr1.map(item => {
|
||||
return (
|
||||
<ListGroupItem className='draggable' key={item.id}>
|
||||
<Media>
|
||||
<Media left tag='div'>
|
||||
<Media
|
||||
object
|
||||
src={item.img}
|
||||
className='rounded-circle mr-2'
|
||||
alt='Generic placeholder image'
|
||||
height='50'
|
||||
width='50'
|
||||
/>
|
||||
</Media>
|
||||
<Media body>
|
||||
<h5 className='mt-0'>{item.name}</h5>
|
||||
{item.content}
|
||||
</Media>
|
||||
</Media>
|
||||
</ListGroupItem>
|
||||
)
|
||||
})}
|
||||
</ReactSortable>
|
||||
</Col>
|
||||
<Col md='6' sm='12'>
|
||||
<h4 className='my-1'>People Group 2</h4>
|
||||
<ReactSortable
|
||||
tag='ul'
|
||||
className='list-group list-group-flush sortable'
|
||||
group='shared-multi-drag-group'
|
||||
list={listArr2}
|
||||
setList={setListArr2}
|
||||
>
|
||||
{listArr2.map(item => {
|
||||
return (
|
||||
<ListGroupItem className='draggable' key={item.id}>
|
||||
<Media>
|
||||
<Media left tag='div'>
|
||||
<Media
|
||||
object
|
||||
src={item.img}
|
||||
className='rounded-circle mr-2'
|
||||
alt='Generic placeholder image'
|
||||
height='50'
|
||||
width='50'
|
||||
/>
|
||||
</Media>
|
||||
<Media body>
|
||||
<h5 className='mt-0'>{item.name}</h5>
|
||||
{item.content}
|
||||
</Media>
|
||||
</Media>
|
||||
</ListGroupItem>
|
||||
)
|
||||
})}
|
||||
</ReactSortable>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default DndMultiDrag
|
@ -1,168 +0,0 @@
|
||||
import { useState } from 'react'
|
||||
import { ReactSortable } from 'react-sortablejs'
|
||||
import img1 from '@src/assets/images/portrait/small/avatar-s-12.jpg'
|
||||
import img2 from '@src/assets/images/portrait/small/avatar-s-1.jpg'
|
||||
import img3 from '@src/assets/images/portrait/small/avatar-s-2.jpg'
|
||||
import img4 from '@src/assets/images/portrait/small/avatar-s-3.jpg'
|
||||
import img5 from '@src/assets/images/portrait/small/avatar-s-4.jpg'
|
||||
import img6 from '@src/assets/images/portrait/small/avatar-s-5.jpg'
|
||||
import img7 from '@src/assets/images/portrait/small/avatar-s-6.jpg'
|
||||
import img8 from '@src/assets/images/portrait/small/avatar-s-7.jpg'
|
||||
import img9 from '@src/assets/images/portrait/small/avatar-s-8.jpg'
|
||||
import img10 from '@src/assets/images/portrait/small/avatar-s-9.jpg'
|
||||
import { Card, CardHeader, CardTitle, CardBody, CardText, Row, Col, ListGroupItem, Media } from 'reactstrap'
|
||||
|
||||
const array = {
|
||||
list1: [
|
||||
{
|
||||
id: '1',
|
||||
img: img1,
|
||||
name: 'Mary S. Navarre',
|
||||
content: 'Chupa chups tiramisu apple pie biscuit sweet roll bonbon macaroon toffee icing.'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
img: img2,
|
||||
name: 'Samuel M. Ellis',
|
||||
content: 'Toffee powder marzipan tiramisu. Cake cake dessert danish.'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
img: img3,
|
||||
name: 'Sandra C. Toney',
|
||||
content: 'Sugar plum fruitcake gummies marzipan liquorice tiramisu. Pastry liquorice chupa.'
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
img: img4,
|
||||
name: 'Cleveland C. Goins',
|
||||
content: 'Toffee powder marzipan tiramisu. Cake cake dessert danish.'
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
img: img5,
|
||||
name: 'Linda M. English',
|
||||
content: 'Chupa chups tiramisu apple pie biscuit sweet roll bonbon macaroon toffee icing.'
|
||||
}
|
||||
],
|
||||
list2: [
|
||||
{
|
||||
id: '6',
|
||||
img: img6,
|
||||
name: 'Alexandria I. Smelser',
|
||||
content: 'Toffee powder marzipan tiramisu. Cake cake dessert danish.'
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
img: img7,
|
||||
name: 'Oscar N. Pool',
|
||||
content: 'Sugar plum fruitcake gummies marzipan liquorice tiramisu. Pastry liquorice chupsake.'
|
||||
},
|
||||
{
|
||||
id: '8',
|
||||
img: img8,
|
||||
name: 'Kathy A. Alvarado',
|
||||
content: 'Chupa chups tiramisu apple pie biscuit sweet roll bonbon macaroon toffee icing.'
|
||||
},
|
||||
{
|
||||
id: '9',
|
||||
img: img9,
|
||||
name: 'James E. White',
|
||||
content: 'Toffee powder marzipan tiramisu. Cake cake dessert danish.'
|
||||
},
|
||||
{
|
||||
id: '10',
|
||||
img: img10,
|
||||
name: 'Roberta R. Babin',
|
||||
content: 'Chupa chups tiramisu apple pie biscuit sweet roll bonbon macaroon toffee icing.'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const DndMultiple = () => {
|
||||
const [listArr1, setListArr1] = useState(array.list1)
|
||||
const [listArr2, setListArr2] = useState(array.list2)
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Multiple Lists</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<CardText>
|
||||
Use <code>group</code> prop to create a multiple list Drag & Drop.
|
||||
</CardText>
|
||||
<Row>
|
||||
<Col md='6' sm='12'>
|
||||
<h4 className='my-1'>People Group 1</h4>
|
||||
<ReactSortable
|
||||
tag='ul'
|
||||
className='list-group list-group-flush sortable'
|
||||
group='shared-group'
|
||||
list={listArr1}
|
||||
setList={setListArr1}
|
||||
>
|
||||
{listArr1.map(item => {
|
||||
return (
|
||||
<ListGroupItem className='draggable' key={item.id}>
|
||||
<Media>
|
||||
<Media left tag='div'>
|
||||
<Media
|
||||
object
|
||||
src={item.img}
|
||||
className='rounded-circle mr-2'
|
||||
alt='Generic placeholder image'
|
||||
height='50'
|
||||
width='50'
|
||||
/>
|
||||
</Media>
|
||||
<Media body>
|
||||
<h5 className='mt-0'>{item.name}</h5>
|
||||
{item.content}
|
||||
</Media>
|
||||
</Media>
|
||||
</ListGroupItem>
|
||||
)
|
||||
})}
|
||||
</ReactSortable>
|
||||
</Col>
|
||||
<Col md='6' sm='12'>
|
||||
<h4 className='my-1'>People Group 2</h4>
|
||||
<ReactSortable
|
||||
tag='ul'
|
||||
className='list-group list-group-flush sortable'
|
||||
group='shared-group'
|
||||
list={listArr2}
|
||||
setList={setListArr2}
|
||||
>
|
||||
{listArr2.map(item => {
|
||||
return (
|
||||
<ListGroupItem className='draggable' key={item.id}>
|
||||
<Media>
|
||||
<Media left tag='div'>
|
||||
<Media
|
||||
object
|
||||
src={item.img}
|
||||
className='rounded-circle mr-2'
|
||||
alt='Generic placeholder image'
|
||||
height='50'
|
||||
width='50'
|
||||
/>
|
||||
</Media>
|
||||
<Media body>
|
||||
<h5 className='mt-0'>{item.name}</h5>
|
||||
{item.content}
|
||||
</Media>
|
||||
</Media>
|
||||
</ListGroupItem>
|
||||
)
|
||||
})}
|
||||
</ReactSortable>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default DndMultiple
|
@ -1,45 +0,0 @@
|
||||
import { Fragment } from 'react'
|
||||
import DndClone from './DndClone'
|
||||
import DndCards from './DndCards'
|
||||
import DndHandle from './DndHandle'
|
||||
import { Row, Col } from 'reactstrap'
|
||||
import DndMultiple from './DndMultiple'
|
||||
import DndMultiDrag from './DndMultiDrag'
|
||||
import DndListGroup from './DndListGroup'
|
||||
import ExtensionsHeader from '@components/extensions-header'
|
||||
|
||||
import '@styles/react/libs/drag-and-drop/drag-and-drop.scss'
|
||||
|
||||
const DragAndDrop = () => {
|
||||
return (
|
||||
<Fragment>
|
||||
<ExtensionsHeader
|
||||
title='React Sortablejs'
|
||||
subTitle='Sortablejs wrapper for React'
|
||||
link='https://github.com/SortableJS/react-sortablejs'
|
||||
/>
|
||||
<Row>
|
||||
<Col sm='12'>
|
||||
<DndCards />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<DndListGroup />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<DndMultiple />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<DndClone />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<DndHandle />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<DndMultiDrag />
|
||||
</Col>
|
||||
</Row>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default DragAndDrop
|
@ -1,81 +0,0 @@
|
||||
import { Fragment, useContext } from 'react'
|
||||
import { Row, Col, Card, CardHeader, CardTitle, CardBody, CustomInput } from 'reactstrap'
|
||||
import ExtensionsHeader from '@components/extensions-header'
|
||||
import { IntlContext } from '../../../utility/context/Internationalization'
|
||||
import { FormattedMessage } from 'react-intl'
|
||||
const I18nExtension = () => {
|
||||
const context = useContext(IntlContext)
|
||||
return (
|
||||
<Fragment>
|
||||
<ExtensionsHeader
|
||||
title='React Intl'
|
||||
subTitle='This library provides React components and an API to format dates, numbers, and strings, including pluralization and handling translations.'
|
||||
link='https://www.npmjs.com/package/react-intl'
|
||||
/>
|
||||
|
||||
<Row>
|
||||
<Col sm='12'>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Change Locale</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<div className='language-options'>
|
||||
<CustomInput
|
||||
type='radio'
|
||||
id='radio-en'
|
||||
name='i18n-lang-radio'
|
||||
onClick={() => {
|
||||
context.switchLanguage('en')
|
||||
}}
|
||||
label='English'
|
||||
className='mb-1'
|
||||
defaultChecked={context.locale === 'en'}
|
||||
/>
|
||||
<CustomInput
|
||||
type='radio'
|
||||
id='radio-fr'
|
||||
name='i18n-lang-radio'
|
||||
onClick={() => {
|
||||
context.switchLanguage('fr')
|
||||
}}
|
||||
label='French'
|
||||
className='mb-1'
|
||||
defaultChecked={context.locale === 'fr'}
|
||||
/>
|
||||
<CustomInput
|
||||
type='radio'
|
||||
id='radio-de'
|
||||
name='i18n-lang-radio'
|
||||
onClick={() => {
|
||||
context.switchLanguage('de')
|
||||
}}
|
||||
label='German'
|
||||
className='mb-1'
|
||||
defaultChecked={context.locale === 'de'}
|
||||
/>
|
||||
<CustomInput
|
||||
type='radio'
|
||||
id='radio-pt'
|
||||
name='i18n-lang-radio'
|
||||
onClick={() => {
|
||||
context.switchLanguage('pt')
|
||||
}}
|
||||
label='Portuguese'
|
||||
className='mb-1'
|
||||
defaultChecked={context.locale === 'pt'}
|
||||
/>
|
||||
</div>
|
||||
<div className='border p-2 mt-3'>
|
||||
<h5 className='mb-1'>Title</h5>
|
||||
<FormattedMessage id='text' />
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default I18nExtension
|
@ -1,245 +0,0 @@
|
||||
import { Fragment, useState, useRef } from 'react'
|
||||
import ExtensionsHeader from '@components/extensions-header'
|
||||
import XLSX from 'xlsx'
|
||||
import * as FileSaver from 'file-saver'
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
Card,
|
||||
CardBody,
|
||||
Button,
|
||||
Table,
|
||||
Modal,
|
||||
ModalHeader,
|
||||
ModalBody,
|
||||
ModalFooter,
|
||||
Input,
|
||||
FormGroup,
|
||||
CustomInput,
|
||||
Label
|
||||
} from 'reactstrap'
|
||||
|
||||
const initialData = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Leanne Graham',
|
||||
username: 'Bret',
|
||||
email: 'Sincere@april.biz',
|
||||
website: 'hildegard.org'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'Ervin Howell',
|
||||
username: 'Antonette',
|
||||
email: 'Shanna@melissa.tv',
|
||||
website: 'anastasia.net'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'Clementine Bauch',
|
||||
username: 'Samantha',
|
||||
email: 'Nathan@yesenia.net',
|
||||
website: 'ramiro.info'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: 'Patricia Lebsack',
|
||||
username: 'Karianne',
|
||||
email: 'Julianne.OConner@kory.org',
|
||||
website: 'kale.biz'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: 'Chelsey Dietrich',
|
||||
username: 'Kamren',
|
||||
email: 'Lucio_Hettinger@annie.ca',
|
||||
website: 'demarco.info'
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: 'Mrs. Dennis Schulist',
|
||||
username: 'Leopoldo_Corkery',
|
||||
email: 'Karley_Dach@jasper.info',
|
||||
website: 'ola.org'
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: 'Kurtis Weissnat',
|
||||
username: 'Elwyn.Skiles',
|
||||
email: 'Telly.Hoeger@billy.biz',
|
||||
website: 'elvis.io'
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: 'Nicholas Runolfsdottir V',
|
||||
username: 'Maxime_Nienow',
|
||||
email: 'Sherwood@rosamond.me',
|
||||
website: 'jacynthe.com'
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: 'Glenna Reichert',
|
||||
username: 'Delphine',
|
||||
email: 'Chaim_McDermott@dana.io',
|
||||
website: 'conrad.com'
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: 'Clementina DuBuque',
|
||||
username: 'Moriah.Stanton',
|
||||
email: 'Rey.Padberg@karina.biz',
|
||||
website: 'ambrose.net'
|
||||
}
|
||||
]
|
||||
|
||||
const Export = () => {
|
||||
const tableRef = useRef()
|
||||
|
||||
const [data] = useState(initialData)
|
||||
const [filteredData, setFilteredData] = useState([])
|
||||
const [value, setValue] = useState('')
|
||||
const [modal, setModal] = useState(false)
|
||||
const [fileName, setFileName] = useState('')
|
||||
const [fileFormat, setFileFormat] = useState('xlsx')
|
||||
|
||||
const toggleModal = () => {
|
||||
setModal(!modal)
|
||||
}
|
||||
|
||||
const handleFilter = e => {
|
||||
const dataArr = data
|
||||
let filteredData = []
|
||||
const value = e.target.value
|
||||
setValue(value)
|
||||
if (value.length) {
|
||||
filteredData = dataArr.filter(col => {
|
||||
const startsWithCondition =
|
||||
col.name.toLowerCase().startsWith(value.toLowerCase()) ||
|
||||
col.email.toLowerCase().startsWith(value.toLowerCase()) ||
|
||||
col.website.toLowerCase().startsWith(value.toLowerCase()) ||
|
||||
col.id.toString().toLowerCase().startsWith(value.toLowerCase())
|
||||
|
||||
const includesCondition =
|
||||
col.name.toLowerCase().includes(value.toLowerCase()) ||
|
||||
col.email.toLowerCase().includes(value.toLowerCase()) ||
|
||||
col.website.toLowerCase().includes(value.toLowerCase()) ||
|
||||
col.id.toString().toLowerCase().includes(value.toLowerCase())
|
||||
|
||||
if (startsWithCondition) return startsWithCondition
|
||||
else if (!startsWithCondition && includesCondition) return includesCondition
|
||||
else return null
|
||||
})
|
||||
setFilteredData(filteredData)
|
||||
setValue(value)
|
||||
}
|
||||
}
|
||||
|
||||
const handleExport = () => {
|
||||
toggleModal()
|
||||
const bookType = fileFormat
|
||||
const wb = XLSX.utils.table_to_book(tableRef.current, { sheet: 'Sheet JS' })
|
||||
const wbout = XLSX.write(wb, { bookType, bookSST: true, type: 'binary' })
|
||||
|
||||
const s2ab = s => {
|
||||
const buf = new ArrayBuffer(s.length)
|
||||
const view = new Uint8Array(buf)
|
||||
for (let i = 0; i < s.length; i++) view[i] = s.charCodeAt(i) & 0xff
|
||||
return buf
|
||||
}
|
||||
const file = fileName.length ? `${fileName}.${fileFormat}` : `excel-sheet.${fileFormat}`
|
||||
|
||||
return FileSaver.saveAs(new Blob([s2ab(wbout)], { type: 'application/octet-stream' }), file)
|
||||
}
|
||||
|
||||
const array = value ? filteredData : data
|
||||
const renderTableData = array.map(col => {
|
||||
return (
|
||||
<tr key={col.id}>
|
||||
<td>{col.email}</td>
|
||||
<td>{col.name}</td>
|
||||
<td>{col.website}</td>
|
||||
<td>{col.id}</td>
|
||||
</tr>
|
||||
)
|
||||
})
|
||||
return (
|
||||
<Fragment>
|
||||
<ExtensionsHeader
|
||||
title='XLSX'
|
||||
subTitle='Xlsx is a parser and writer for various spreadsheet formats'
|
||||
link='https://github.com/AdeleD/react-paginate'
|
||||
/>
|
||||
<Row className='export-component'>
|
||||
<Col sm='12'>
|
||||
<Card>
|
||||
<CardBody className='pb-0'>
|
||||
<div className='d-flex justify-content-between flex-wrap flex-sm-row flex-column'>
|
||||
<Button.Ripple color='primary' onClick={() => toggleModal()}>
|
||||
Export
|
||||
</Button.Ripple>
|
||||
<div className='d-flex align-items-center justify-content-end mt-sm-0 mt-1'>
|
||||
<Label for='search-input' className='mr-1'>
|
||||
Search
|
||||
</Label>
|
||||
<Input id='search-input' bsSize='sm' type='text' value={value} onChange={e => handleFilter(e)} />
|
||||
</div>
|
||||
</div>
|
||||
</CardBody>
|
||||
<Table innerRef={tableRef} className='table-hover-animation mt-2' responsive>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<th>Name</th>
|
||||
<th>Website</th>
|
||||
<th>Rank</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{renderTableData}</tbody>
|
||||
</Table>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
<Modal
|
||||
isOpen={modal}
|
||||
toggle={() => toggleModal()}
|
||||
className='modal-dialog-centered'
|
||||
onClosed={() => setFileName('')}
|
||||
>
|
||||
<ModalHeader toggle={() => toggleModal()}>Export To Excel</ModalHeader>
|
||||
<ModalBody>
|
||||
<FormGroup>
|
||||
<Input
|
||||
type='text'
|
||||
value={fileName}
|
||||
onChange={e => setFileName(e.target.value)}
|
||||
placeholder='Enter File Name'
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<CustomInput
|
||||
type='select'
|
||||
id='selectFileFormat'
|
||||
name='customSelect'
|
||||
value={fileFormat}
|
||||
onChange={e => setFileFormat(e.target.value)}
|
||||
>
|
||||
<option>xlsx</option>
|
||||
<option>csv</option>
|
||||
<option>txt</option>
|
||||
</CustomInput>
|
||||
</FormGroup>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color='primary' onClick={() => handleExport()}>
|
||||
Export
|
||||
</Button>
|
||||
<Button color='flat-danger' onClick={() => toggleModal()}>
|
||||
Cancel
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default Export
|
@ -1,295 +0,0 @@
|
||||
import { Fragment, useState } from 'react'
|
||||
import ExtensionsHeader from '@components/extensions-header'
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
Card,
|
||||
CardBody,
|
||||
Button,
|
||||
Table,
|
||||
Modal,
|
||||
ModalHeader,
|
||||
ModalBody,
|
||||
ModalFooter,
|
||||
Input,
|
||||
FormGroup,
|
||||
CustomInput,
|
||||
Label
|
||||
} from 'reactstrap'
|
||||
import classnames from 'classnames'
|
||||
import XLSX from 'xlsx'
|
||||
|
||||
const initialData = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Leanne Graham',
|
||||
username: 'Bret',
|
||||
email: 'Sincere@april.biz',
|
||||
website: 'hildegard.org'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'Ervin Howell',
|
||||
username: 'Antonette',
|
||||
email: 'Shanna@melissa.tv',
|
||||
website: 'anastasia.net'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'Clementine Bauch',
|
||||
username: 'Samantha',
|
||||
email: 'Nathan@yesenia.net',
|
||||
website: 'ramiro.info'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: 'Patricia Lebsack',
|
||||
username: 'Karianne',
|
||||
email: 'Julianne.OConner@kory.org',
|
||||
website: 'kale.biz'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: 'Chelsey Dietrich',
|
||||
username: 'Kamren',
|
||||
email: 'Lucio_Hettinger@annie.ca',
|
||||
website: 'demarco.info'
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: 'Mrs. Dennis Schulist',
|
||||
username: 'Leopoldo_Corkery',
|
||||
email: 'Karley_Dach@jasper.info',
|
||||
website: 'ola.org'
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: 'Kurtis Weissnat',
|
||||
username: 'Elwyn.Skiles',
|
||||
email: 'Telly.Hoeger@billy.biz',
|
||||
website: 'elvis.io'
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: 'Nicholas Runolfsdottir V',
|
||||
username: 'Maxime_Nienow',
|
||||
email: 'Sherwood@rosamond.me',
|
||||
website: 'jacynthe.com'
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: 'Glenna Reichert',
|
||||
username: 'Delphine',
|
||||
email: 'Chaim_McDermott@dana.io',
|
||||
website: 'conrad.com'
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: 'Clementina DuBuque',
|
||||
username: 'Moriah.Stanton',
|
||||
email: 'Rey.Padberg@karina.biz',
|
||||
website: 'ambrose.net'
|
||||
}
|
||||
]
|
||||
|
||||
const ExportSelected = () => {
|
||||
const [data] = useState(initialData)
|
||||
const [filteredData, setFilteredData] = useState([])
|
||||
const [dataToExport, setDataToExport] = useState([])
|
||||
const [value, setValue] = useState('')
|
||||
const [modal, setModal] = useState(false)
|
||||
const [fileName, setFileName] = useState('')
|
||||
const [fileFormat, setFileFormat] = useState('xlsx')
|
||||
const [selectedRows, setSelectedRows] = useState([])
|
||||
|
||||
const toggleModal = () => setModal(!modal)
|
||||
|
||||
const handleFilter = e => {
|
||||
let filteredData = []
|
||||
const value = e.target.value
|
||||
setValue(value)
|
||||
if (value.length) {
|
||||
filteredData = data.filter(col => {
|
||||
const startsWithCondition =
|
||||
col.name.toLowerCase().startsWith(value.toLowerCase()) ||
|
||||
col.email.toLowerCase().startsWith(value.toLowerCase()) ||
|
||||
col.website.toLowerCase().startsWith(value.toLowerCase()) ||
|
||||
col.id.toString().toLowerCase().startsWith(value.toLowerCase())
|
||||
|
||||
const includesCondition =
|
||||
col.name.toLowerCase().includes(value.toLowerCase()) ||
|
||||
col.email.toLowerCase().includes(value.toLowerCase()) ||
|
||||
col.website.toLowerCase().includes(value.toLowerCase()) ||
|
||||
col.id.toString().toLowerCase().includes(value.toLowerCase())
|
||||
|
||||
if (startsWithCondition) return startsWithCondition
|
||||
else if (!startsWithCondition && includesCondition) return includesCondition
|
||||
else return null
|
||||
})
|
||||
setValue(value)
|
||||
setFilteredData(filteredData)
|
||||
}
|
||||
}
|
||||
|
||||
const handleExport = () => {
|
||||
const exportArr = dataToExport
|
||||
data.map(item => {
|
||||
if (selectedRows.includes(item.id)) {
|
||||
return exportArr.push(item)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
})
|
||||
setDataToExport([...exportArr])
|
||||
const name = fileName.length ? `${fileName}.${fileFormat}` : `excel-sheet.${fileFormat}`
|
||||
const wb = XLSX.utils.json_to_sheet(dataToExport)
|
||||
const wbout = XLSX.utils.book_new()
|
||||
XLSX.utils.book_append_sheet(wbout, wb, 'test')
|
||||
XLSX.writeFile(wbout, name)
|
||||
toggleModal()
|
||||
}
|
||||
|
||||
const handleSelect = id => {
|
||||
const selectedRowsArr = selectedRows
|
||||
if (!selectedRowsArr.includes(id)) {
|
||||
selectedRowsArr.push(id)
|
||||
} else if (selectedRowsArr.includes(id)) {
|
||||
selectedRowsArr.splice(selectedRowsArr.indexOf(id), 1)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
setSelectedRows([...selectedRowsArr])
|
||||
}
|
||||
|
||||
const handleSelectAll = () => {
|
||||
let selectedRowsArr = selectedRows
|
||||
if (selectedRowsArr.length < data.length) {
|
||||
const ids = data.map(i => i.id)
|
||||
selectedRowsArr = ids
|
||||
} else if (selectedRowsArr.length === data.length) {
|
||||
selectedRowsArr = []
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
|
||||
setSelectedRows(selectedRowsArr)
|
||||
}
|
||||
|
||||
const array = value ? filteredData : data
|
||||
const renderTableData = array.map(col => {
|
||||
return (
|
||||
<tr
|
||||
key={col.id}
|
||||
className={classnames({
|
||||
selected: selectedRows.includes(col.id)
|
||||
})}
|
||||
>
|
||||
<td>
|
||||
<CustomInput
|
||||
type='checkbox'
|
||||
id={col.id}
|
||||
label=''
|
||||
checked={!!selectedRows.includes(col.id)}
|
||||
onChange={() => handleSelect(col.id)}
|
||||
/>
|
||||
</td>
|
||||
<td>{col.email}</td>
|
||||
<td>{col.name}</td>
|
||||
<td>{col.website}</td>
|
||||
<td>{col.id}</td>
|
||||
</tr>
|
||||
)
|
||||
})
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<ExtensionsHeader
|
||||
title='XLSX'
|
||||
subTitle='Xlsx is a parser and writer for various spreadsheet formats'
|
||||
link='https://github.com/AdeleD/react-paginate'
|
||||
/>
|
||||
<Row className='export-component'>
|
||||
<Col sm='12'>
|
||||
<Card>
|
||||
<CardBody className='pb-0'>
|
||||
<div className='d-flex flex-wrap justify-content-between'>
|
||||
<Button.Ripple color='primary' onClick={() => toggleModal()}>
|
||||
Export Selected
|
||||
</Button.Ripple>
|
||||
<div className='d-flex align-items-center justify-content-end'>
|
||||
<Label for='search-input' className='mr-1'>
|
||||
Search
|
||||
</Label>
|
||||
<Input id='search-input' bsSize='sm' type='text' value={value} onChange={e => handleFilter(e)} />
|
||||
</div>
|
||||
</div>
|
||||
</CardBody>
|
||||
<Table className='table-hover-animation mt-2' responsive>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<CustomInput
|
||||
type='checkbox'
|
||||
id='select-all'
|
||||
label=''
|
||||
checked={!!selectedRows.length}
|
||||
onChange={e => handleSelectAll()}
|
||||
/>
|
||||
</th>
|
||||
<th>Email</th>
|
||||
<th>Name</th>
|
||||
<th>Website</th>
|
||||
<th>Rank</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{renderTableData}</tbody>
|
||||
</Table>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
<Modal
|
||||
isOpen={modal}
|
||||
toggle={() => toggleModal()}
|
||||
className='modal-dialog-centered'
|
||||
onClosed={() => setFileName('')}
|
||||
>
|
||||
<ModalHeader toggle={() => toggleModal()}>Export To Excel</ModalHeader>
|
||||
<ModalBody>
|
||||
<FormGroup>
|
||||
<Input
|
||||
type='text'
|
||||
value={fileName}
|
||||
onChange={e => setFileName(e.target.value)}
|
||||
placeholder='Enter File Name'
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<CustomInput
|
||||
type='select'
|
||||
id='selectFileFormat'
|
||||
name='customSelect'
|
||||
value={fileFormat}
|
||||
onChange={e => {
|
||||
setFileFormat(e.target.value)
|
||||
}}
|
||||
>
|
||||
<option>xlsx</option>
|
||||
<option>csv</option>
|
||||
<option>txt</option>
|
||||
</CustomInput>
|
||||
</FormGroup>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color='primary' onClick={() => handleExport()}>
|
||||
Export
|
||||
</Button>
|
||||
<Button color='flat-danger' onClick={() => toggleModal()}>
|
||||
Cancel
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default ExportSelected
|
@ -1,170 +0,0 @@
|
||||
import { Fragment, useState } from 'react'
|
||||
import XLSX from 'xlsx'
|
||||
import Uppy from '@uppy/core'
|
||||
import { X } from 'react-feather'
|
||||
import { DragDrop } from '@uppy/react'
|
||||
import Avatar from '@components/avatar'
|
||||
import { toast } from 'react-toastify'
|
||||
import ExtensionsHeader from '@components/extensions-header'
|
||||
import { Row, Col, Card, CardBody, Table, CardHeader, CardTitle, Input, Label } from 'reactstrap'
|
||||
|
||||
import 'uppy/dist/uppy.css'
|
||||
import '@uppy/status-bar/dist/style.css'
|
||||
import '@styles/react/libs/file-uploader/file-uploader.scss'
|
||||
|
||||
const ErrorToast = () => (
|
||||
<Fragment>
|
||||
<div className='toastify-header'>
|
||||
<div className='title-wrapper'>
|
||||
<Avatar size='sm' color='danger' icon={<X size={12} />} />
|
||||
<h6 className='toast-title'>Error!</h6>
|
||||
</div>
|
||||
<small className='text-muted'>a second ago</small>
|
||||
</div>
|
||||
<div className='toastify-body'>
|
||||
<span role='img' aria-label='toast-text'>
|
||||
👋 You can only upload <span className='font-weight-bolder'>.xlsx</span>,{' '}
|
||||
<span className='font-weight-bolder'>.xls</span> & <span className='font-weight-bolder'>.csv</span> Files!.
|
||||
</span>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
|
||||
const Import = () => {
|
||||
const [tableData, setTableData] = useState([])
|
||||
const [filteredData, setFilteredData] = useState([])
|
||||
const [value, setValue] = useState('')
|
||||
const [name, setName] = useState('')
|
||||
|
||||
const uppy = new Uppy({
|
||||
restrictions: { maxNumberOfFiles: 1 },
|
||||
autoProceed: true
|
||||
})
|
||||
|
||||
const getTableData = (arr, name) => {
|
||||
setTableData(arr)
|
||||
setName(name)
|
||||
}
|
||||
|
||||
uppy.on('complete', result => {
|
||||
const reader = new FileReader()
|
||||
reader.onload = function () {
|
||||
const fileData = reader.result
|
||||
const wb = XLSX.read(fileData, { type: 'binary' })
|
||||
|
||||
wb.SheetNames.forEach(function (sheetName) {
|
||||
const rowObj = XLSX.utils.sheet_to_row_object_array(wb.Sheets[sheetName])
|
||||
getTableData(rowObj, result.successful[0].data.name)
|
||||
})
|
||||
}
|
||||
if (result.successful[0].extension === 'xlsx') {
|
||||
reader.readAsBinaryString(result.successful[0].data)
|
||||
} else {
|
||||
toast.error(<ErrorToast />, { hideProgressBar: true })
|
||||
}
|
||||
})
|
||||
|
||||
const handleFilter = e => {
|
||||
const data = tableData
|
||||
let filteredData = []
|
||||
const value = e.target.value
|
||||
setValue(value)
|
||||
|
||||
if (value.length) {
|
||||
filteredData = data.filter(col => {
|
||||
const keys = Object.keys(col)
|
||||
|
||||
const startsWithCondition = keys.filter(key => {
|
||||
return col[key].toString().toLowerCase().startsWith(value.toLowerCase())
|
||||
})
|
||||
|
||||
const includesCondition = keys.filter(key => col[key].toString().toLowerCase().includes(value.toLowerCase()))
|
||||
|
||||
if (startsWithCondition.length) return col[startsWithCondition]
|
||||
else if (!startsWithCondition && includesCondition.length) return col[includesCondition]
|
||||
else return null
|
||||
})
|
||||
setFilteredData(filteredData)
|
||||
setValue(value)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
/*eslint-disable */
|
||||
const headArr = tableData.length
|
||||
? tableData.map((col, index) => {
|
||||
if (index === 0) return [...Object.keys(col)]
|
||||
else return null
|
||||
})
|
||||
: []
|
||||
/*eslint-enable */
|
||||
const dataArr = value.length ? filteredData : tableData.length && !value.length ? tableData : null
|
||||
|
||||
const renderTableBody = () => {
|
||||
if (dataArr !== null && dataArr.length) {
|
||||
return dataArr.map((col, index) => {
|
||||
const keys = Object.keys(col)
|
||||
const renderTd = keys.map((key, index) => <td key={index}>{col[key]}</td>)
|
||||
return <tr key={index}>{renderTd}</tr>
|
||||
})
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const renderTableHead = () => {
|
||||
if (headArr.length) {
|
||||
return headArr[0].map((head, index) => {
|
||||
return <th key={index}>{head}</th>
|
||||
})
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<ExtensionsHeader
|
||||
title='XLSX'
|
||||
subTitle='Xlsx is a parser and writer for various spreadsheet formats'
|
||||
link='https://github.com/AdeleD/react-paginate'
|
||||
/>
|
||||
<Row className='import-component'>
|
||||
<Col sm='12'>
|
||||
<Card>
|
||||
<CardBody>
|
||||
<Row>
|
||||
<Col sm='12'>
|
||||
<DragDrop uppy={uppy} />
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
{tableData.length ? (
|
||||
<Col sm='12'>
|
||||
<Card>
|
||||
<CardHeader className='justify-content-between flex-wrap'>
|
||||
<CardTitle tag='h4'>{name}</CardTitle>
|
||||
<div className='d-flex align-items-center justify-content-end'>
|
||||
<Label for='search-input' className='mr-1'>
|
||||
Search
|
||||
</Label>
|
||||
<Input id='search-input' type='text' bsSize='sm' value={value} onChange={e => handleFilter(e)} />
|
||||
</div>
|
||||
</CardHeader>
|
||||
<Table className='table-hover-animation' responsive>
|
||||
<thead>
|
||||
<tr>{renderTableHead()}</tr>
|
||||
</thead>
|
||||
<tbody>{renderTableBody()}</tbody>
|
||||
</Table>
|
||||
</Card>
|
||||
</Col>
|
||||
) : null}
|
||||
</Row>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default Import
|
@ -1,32 +0,0 @@
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import ReactPaginate from 'react-paginate'
|
||||
const BasicPagination = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Basic</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<ReactPaginate
|
||||
pageCount={10}
|
||||
nextLabel={''}
|
||||
breakLabel={'...'}
|
||||
pageRangeDisplayed={5}
|
||||
marginPagesDisplayed={2}
|
||||
activeClassName={'active'}
|
||||
pageClassName={'page-item'}
|
||||
previousLabel={''}
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next-item'}
|
||||
previousClassName={'page-item prev-item'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
containerClassName={'pagination react-paginate no-navigation'}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
export default BasicPagination
|
@ -1,33 +0,0 @@
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import ReactPaginate from 'react-paginate'
|
||||
|
||||
const PaginationDanger = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Danger</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<ReactPaginate
|
||||
pageCount={10}
|
||||
nextLabel={''}
|
||||
breakLabel={'...'}
|
||||
pageRangeDisplayed={5}
|
||||
marginPagesDisplayed={2}
|
||||
activeClassName={'active'}
|
||||
pageClassName={'page-item'}
|
||||
previousLabel={''}
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next'}
|
||||
previousClassName={'page-item prev'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
containerClassName={'pagination react-paginate pagination-danger'}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
export default PaginationDanger
|
@ -1,33 +0,0 @@
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import ReactPaginate from 'react-paginate'
|
||||
|
||||
const IconPagination = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Icon Only</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<ReactPaginate
|
||||
pageCount={10}
|
||||
nextLabel={''}
|
||||
breakLabel={'...'}
|
||||
pageRangeDisplayed={5}
|
||||
marginPagesDisplayed={2}
|
||||
activeClassName={'active'}
|
||||
pageClassName={'page-item'}
|
||||
previousLabel={''}
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next'}
|
||||
previousClassName={'page-item prev'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
containerClassName={'pagination react-paginate'}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
export default IconPagination
|
@ -1,41 +0,0 @@
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import ReactPaginate from 'react-paginate'
|
||||
|
||||
const Previous = () => {
|
||||
return <span className='align-middle d-none d-md-inline-block'>Prev</span>
|
||||
}
|
||||
|
||||
const Next = () => {
|
||||
return <span className='align-middle d-none d-md-inline-block'>Next </span>
|
||||
}
|
||||
|
||||
const IconTextPagination = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>With icon and text</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<ReactPaginate
|
||||
pageCount={10}
|
||||
nextLabel={<Next />}
|
||||
breakLabel={'...'}
|
||||
pageRangeDisplayed={5}
|
||||
marginPagesDisplayed={2}
|
||||
activeClassName={'active'}
|
||||
pageClassName={'page-item'}
|
||||
previousLabel={<Previous />}
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next'}
|
||||
previousClassName={'page-item prev'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
containerClassName={'pagination react-paginate'}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
export default IconTextPagination
|
@ -1,33 +0,0 @@
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import ReactPaginate from 'react-paginate'
|
||||
|
||||
const PaginationInfo = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Info</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<ReactPaginate
|
||||
pageCount={10}
|
||||
nextLabel={''}
|
||||
breakLabel={'...'}
|
||||
pageRangeDisplayed={5}
|
||||
marginPagesDisplayed={2}
|
||||
activeClassName={'active'}
|
||||
pageClassName={'page-item'}
|
||||
previousLabel={''}
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next'}
|
||||
previousClassName={'page-item prev'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
containerClassName={'pagination react-paginate pagination-info'}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
export default PaginationInfo
|
@ -1,74 +0,0 @@
|
||||
import { Card, CardHeader, CardTitle, CardBody, Row, Col } from 'reactstrap'
|
||||
import ReactPaginate from 'react-paginate'
|
||||
|
||||
const PaginationPositions = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Positions</CardTitle>
|
||||
</CardHeader>{' '}
|
||||
<CardBody>
|
||||
<Row>
|
||||
<Col xl='4' md='12'>
|
||||
<h5 className='text-left'>Left Aligned</h5>
|
||||
<ReactPaginate
|
||||
pageCount={5}
|
||||
nextLabel={''}
|
||||
breakLabel={'...'}
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
activeClassName={'active'}
|
||||
pageClassName={'page-item'}
|
||||
previousLabel={''}
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next'}
|
||||
previousClassName={'page-item prev'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
containerClassName={'pagination react-paginate justify-content-start'}
|
||||
/>
|
||||
</Col>
|
||||
<Col xl='4' md='12'>
|
||||
<h5 className='text-center'>Center Aligned</h5>
|
||||
<ReactPaginate
|
||||
pageCount={5}
|
||||
nextLabel={''}
|
||||
breakLabel={'...'}
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
activeClassName={'active'}
|
||||
pageClassName={'page-item'}
|
||||
previousLabel={''}
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next'}
|
||||
previousClassName={'page-item prev'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
containerClassName={'pagination react-paginate justify-content-center'}
|
||||
/>
|
||||
</Col>
|
||||
<Col xl='4' md='12'>
|
||||
<h5 className='text-right'>Right Aligned</h5>
|
||||
<ReactPaginate
|
||||
pageCount={5}
|
||||
nextLabel={''}
|
||||
breakLabel={'...'}
|
||||
activeClassName={'active'}
|
||||
pageClassName={'page-item'}
|
||||
previousLabel={''}
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next'}
|
||||
previousClassName={'page-item prev'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
containerClassName={'pagination react-paginate justify-content-end'}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
export default PaginationPositions
|
@ -1,71 +0,0 @@
|
||||
import { Card, CardHeader, CardTitle, CardBody, Row, Col } from 'reactstrap'
|
||||
import ReactPaginate from 'react-paginate'
|
||||
|
||||
const PaginationSizes = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Sizes</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Row>
|
||||
<Col lg='4' sm='12'>
|
||||
<ReactPaginate
|
||||
pageCount={5}
|
||||
nextLabel={''}
|
||||
breakLabel={'...'}
|
||||
activeClassName={'active'}
|
||||
pageClassName={'page-item'}
|
||||
previousLabel={''}
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next'}
|
||||
previousClassName={'page-item prev'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
containerClassName={'pagination react-paginate pagination-lg'}
|
||||
/>
|
||||
</Col>
|
||||
<Col lg='4' sm='12'>
|
||||
<ReactPaginate
|
||||
pageCount={5}
|
||||
nextLabel={''}
|
||||
breakLabel={'...'}
|
||||
activeClassName={'active'}
|
||||
pageClassName={'page-item'}
|
||||
previousLabel={''}
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next'}
|
||||
previousClassName={'page-item prev'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
containerClassName={'pagination react-paginate'}
|
||||
/>
|
||||
</Col>
|
||||
<Col lg='4' sm='12'>
|
||||
<ReactPaginate
|
||||
pageCount={5}
|
||||
nextLabel={''}
|
||||
breakLabel={'...'}
|
||||
activeClassName={'active'}
|
||||
pageClassName={'page-item'}
|
||||
previousLabel={''}
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next'}
|
||||
previousClassName={'page-item prev'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
containerClassName={'pagination react-paginate pagination-sm'}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
export default PaginationSizes
|
@ -1,33 +0,0 @@
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import ReactPaginate from 'react-paginate'
|
||||
|
||||
const PaginationSuccess = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Success</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<ReactPaginate
|
||||
pageCount={10}
|
||||
nextLabel={''}
|
||||
breakLabel={'...'}
|
||||
pageRangeDisplayed={5}
|
||||
marginPagesDisplayed={2}
|
||||
activeClassName={'active'}
|
||||
pageClassName={'page-item'}
|
||||
previousLabel={''}
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next'}
|
||||
previousClassName={'page-item prev'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
containerClassName={'pagination react-paginate pagination-success'}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
export default PaginationSuccess
|
@ -1,33 +0,0 @@
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import ReactPaginate from 'react-paginate'
|
||||
|
||||
const PaginationWarning = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Warning</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<ReactPaginate
|
||||
pageCount={10}
|
||||
nextLabel={''}
|
||||
breakLabel={'...'}
|
||||
pageRangeDisplayed={5}
|
||||
marginPagesDisplayed={2}
|
||||
activeClassName={'active'}
|
||||
pageClassName={'page-item'}
|
||||
previousLabel={''}
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next'}
|
||||
previousClassName={'page-item prev'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
containerClassName={'pagination react-paginate pagination-warning'}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
export default PaginationWarning
|
@ -1,32 +0,0 @@
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import ReactPaginate from 'react-paginate'
|
||||
const SeparatedPagination = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Separated</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<ReactPaginate
|
||||
pageCount={10}
|
||||
nextLabel={''}
|
||||
breakLabel={'...'}
|
||||
pageRangeDisplayed={5}
|
||||
marginPagesDisplayed={2}
|
||||
activeClassName={'active'}
|
||||
pageClassName={'page-item'}
|
||||
previousLabel={''}
|
||||
nextLinkClassName={'page-link'}
|
||||
nextClassName={'page-item next-item'}
|
||||
previousClassName={'page-item prev-item'}
|
||||
previousLinkClassName={'page-link'}
|
||||
pageLinkClassName={'page-link'}
|
||||
breakClassName='page-item'
|
||||
breakLinkClassName='page-link'
|
||||
containerClassName={'pagination react-paginate'}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
export default SeparatedPagination
|
@ -1,60 +0,0 @@
|
||||
import { Fragment } from 'react'
|
||||
import ExtensionsHeader from '@components/extensions-header'
|
||||
import { Row, Col } from 'reactstrap'
|
||||
import BasicPagination from './BasicPagination'
|
||||
import SepratedPagination from './SepratedPagination'
|
||||
import PaginationIconText from './PaginationIconText'
|
||||
import PaginationIcon from './PaginationIcon'
|
||||
import PaginationSuccess from './PaginationSuccess'
|
||||
import PaginationDanger from './PaginationDanger'
|
||||
import PaginationInfo from './PaginationInfo'
|
||||
import PaginationWarning from './PaginationWarning'
|
||||
import PaginationPositions from './PaginationPositions'
|
||||
import PaginationSizes from './PaginationSizes'
|
||||
|
||||
const ReactPaginate = () => {
|
||||
return (
|
||||
<Fragment>
|
||||
<ExtensionsHeader
|
||||
title='React Paginate'
|
||||
subTitle='A ReactJS component that creates a pagination'
|
||||
link='https://github.com/AdeleD/react-paginate'
|
||||
/>
|
||||
|
||||
<Row>
|
||||
<Col lg='6' md='12' sm='12'>
|
||||
<BasicPagination />
|
||||
</Col>
|
||||
<Col lg='6' md='12' sm='12'>
|
||||
<SepratedPagination />
|
||||
</Col>
|
||||
<Col lg='6' md='12' sm='12'>
|
||||
<PaginationIconText />
|
||||
</Col>
|
||||
<Col lg='6' md='12' sm='12'>
|
||||
<PaginationIcon />
|
||||
</Col>
|
||||
<Col lg='6' md='12' sm='12'>
|
||||
<PaginationSuccess />
|
||||
</Col>
|
||||
<Col lg='6' md='12' sm='12'>
|
||||
<PaginationDanger />
|
||||
</Col>
|
||||
<Col lg='6' md='12' sm='12'>
|
||||
<PaginationInfo />
|
||||
</Col>
|
||||
<Col lg='6' md='12' sm='12'>
|
||||
<PaginationWarning />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<PaginationPositions />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<PaginationSizes />
|
||||
</Col>
|
||||
</Row>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default ReactPaginate
|
@ -1,23 +0,0 @@
|
||||
import Rating from 'react-rating'
|
||||
import { Star } from 'react-feather'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
|
||||
const RatingBasic = ({ filledColor, dir }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Basic</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Rating
|
||||
emptySymbol={<Star size={32} fill='#babfc7' stroke='#babfc7' />}
|
||||
fullSymbol={<Star size={32} fill={filledColor} stroke={filledColor} />}
|
||||
initialRating={2}
|
||||
direction={dir}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default RatingBasic
|
@ -1,38 +0,0 @@
|
||||
import { useState } from 'react'
|
||||
import Rating from 'react-rating'
|
||||
import { Star } from 'react-feather'
|
||||
import { Card, Button, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
|
||||
const RatingControlled = ({ filledColor, dir }) => {
|
||||
const [value, setValue] = useState(0)
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Controlled Ratings</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Rating
|
||||
emptySymbol={<Star size={32} fill='#babfc7' stroke='#babfc7' />}
|
||||
fullSymbol={<Star size={32} fill={filledColor} stroke={filledColor} />}
|
||||
initialRating={value}
|
||||
onChange={e => setValue(e)}
|
||||
direction={dir}
|
||||
/>
|
||||
<div className='demo-inline-spacing'>
|
||||
<Button color='primary' onClick={() => setValue(0)} outline>
|
||||
Reset
|
||||
</Button>
|
||||
<Button color='primary' onClick={() => alert(value)} outline>
|
||||
Get Ratings
|
||||
</Button>
|
||||
<Button color='primary' onClick={() => setValue(3)} outline>
|
||||
Set Ratings to 3
|
||||
</Button>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default RatingControlled
|
@ -1,28 +0,0 @@
|
||||
import Rating from 'react-rating'
|
||||
import { Sun, Cloud, CloudLightning, CloudSnow, CloudDrizzle } from 'react-feather'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
|
||||
const RatingCustomSvg = ({ emptyColor, dir }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Custom SVG</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Rating
|
||||
emptySymbol={<Sun size={32} stroke='#babfc7' />}
|
||||
fullSymbol={[
|
||||
<Cloud size={32} stroke='#babfc7' />,
|
||||
<CloudLightning size={32} stroke='#babfc7' />,
|
||||
<CloudSnow size={32} stroke='#babfc7' />,
|
||||
<CloudDrizzle size={32} stroke='#babfc7' />
|
||||
]}
|
||||
stop={4}
|
||||
direction={dir}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default RatingCustomSvg
|
@ -1,33 +0,0 @@
|
||||
import Rating from 'react-rating'
|
||||
import { Star } from 'react-feather'
|
||||
import RatingsHover from './RatingsHover'
|
||||
import { Card, CardHeader, CardTitle, CardBody, CardText, Row, Col } from 'reactstrap'
|
||||
|
||||
const RatingEvents = ({ filledColor, dir }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Events</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Row>
|
||||
<Col md='6' className='d-flex flex-column align-items-start mb-md-0 mb-1'>
|
||||
<CardText className='font-weight-semibold mb-25'>On Change</CardText>
|
||||
<Rating
|
||||
emptySymbol={<Star size={32} fill='#babfc7' stroke='#babfc7' />}
|
||||
fullSymbol={<Star size={32} fill={filledColor} stroke={filledColor} />}
|
||||
onChange={rate => alert(rate)}
|
||||
direction={dir}
|
||||
/>
|
||||
</Col>
|
||||
<Col md='6' className='d-flex flex-column align-items-start'>
|
||||
<CardText className='font-weight-semibold mb-25'>On Hover</CardText>
|
||||
<RatingsHover filledColor={filledColor} dir={dir} />
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default RatingEvents
|
@ -1,24 +0,0 @@
|
||||
import Rating from 'react-rating'
|
||||
import { Star } from 'react-feather'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
|
||||
const RatingFractional = ({ filledColor, dir }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Fractional</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Rating
|
||||
emptySymbol={<Star size={32} fill='#babfc7' stroke='#babfc7' />}
|
||||
fullSymbol={<Star size={32} fill={filledColor} stroke={filledColor} />}
|
||||
fractions={2}
|
||||
initialRating={2.5}
|
||||
direction={dir}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default RatingFractional
|
@ -1,23 +0,0 @@
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import Rating from 'react-rating'
|
||||
|
||||
const RatingNumbers = props => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Numbers</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Rating
|
||||
emptySymbol={<span className='font-medium-3 mr-50'>-</span>}
|
||||
fullSymbol={[1, 2, 3, 4, 5].map(n => (
|
||||
<span className='font-medium-3 mr-50'>{n}</span>
|
||||
))}
|
||||
direction={props.dir}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default RatingNumbers
|
@ -1,24 +0,0 @@
|
||||
import Rating from 'react-rating'
|
||||
import { Star } from 'react-feather'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
|
||||
const RatingReadOnly = ({ filledColor, dir }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Readonly</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Rating
|
||||
emptySymbol={<Star size={32} fill='#babfc7' stroke='#babfc7' />}
|
||||
fullSymbol={<Star size={32} fill={filledColor} stroke={filledColor} />}
|
||||
readonly
|
||||
initialRating={2}
|
||||
direction={dir}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default RatingReadOnly
|
@ -1,35 +0,0 @@
|
||||
import Rating from 'react-rating'
|
||||
import { Star } from 'react-feather'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
|
||||
const RatingSizes = ({ filledColor, dir }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Sizes</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<h6>Large</h6>
|
||||
<Rating
|
||||
direction={dir}
|
||||
emptySymbol={<Star size={42} fill='#babfc7' stroke='#babfc7' />}
|
||||
fullSymbol={<Star size={42} fill={filledColor} stroke={filledColor} />}
|
||||
/>
|
||||
<h6 className='mt-2'>Default</h6>
|
||||
<Rating
|
||||
direction={dir}
|
||||
emptySymbol={<Star size={32} fill='#babfc7' stroke='#babfc7' />}
|
||||
fullSymbol={<Star size={32} fill={filledColor} stroke={filledColor} />}
|
||||
/>
|
||||
<h6 className='mt-2'>Small</h6>
|
||||
<Rating
|
||||
direction={dir}
|
||||
emptySymbol={<Star size={20} fill='#babfc7' stroke='#babfc7' />}
|
||||
fullSymbol={<Star size={20} fill={filledColor} stroke={filledColor} />}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default RatingSizes
|
@ -1,32 +0,0 @@
|
||||
import { useState, Fragment } from 'react'
|
||||
import Rating from 'react-rating'
|
||||
import { Star } from 'react-feather'
|
||||
|
||||
const RatingsHover = ({ filledColor, dir }) => {
|
||||
const [value, setValue] = useState(0)
|
||||
|
||||
const onHover = rate => {
|
||||
if (rate !== undefined) {
|
||||
setValue(rate)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Rating
|
||||
initialRating={value}
|
||||
id='ratings-hover'
|
||||
emptySymbol={<Star size={32} fill='#babfc7' stroke='#babfc7' />}
|
||||
fullSymbol={<Star size={32} fill={filledColor} stroke={filledColor} />}
|
||||
onHover={rate => onHover(rate)}
|
||||
onChange={rate => setValue(rate)}
|
||||
direction={dir}
|
||||
/>
|
||||
<div className='counter-wrapper mt-1'>
|
||||
<span className='font-weight-bold'>Ratings: {value}</span>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default RatingsHover
|
@ -1,55 +0,0 @@
|
||||
import { Fragment, useContext } from 'react'
|
||||
import { Row, Col } from 'reactstrap'
|
||||
import { useRTL } from '@hooks/useRTL'
|
||||
import RatingBasic from './RatingBasic'
|
||||
import RatingSizes from './RatingSizes'
|
||||
import RatingEvents from './RatingEvents'
|
||||
import RatingNumbers from './RatingNumbers'
|
||||
import RatingReadOnly from './RatingReadOnly'
|
||||
import RatingCustomSvg from './RatingCustomSvg'
|
||||
import RatingFractional from './RatingFractional'
|
||||
import RatingControlled from './RatingControlled'
|
||||
import ExtensionsHeader from '@components/extensions-header'
|
||||
import { ThemeColors } from '@src/utility/context/ThemeColors'
|
||||
|
||||
const Rating = () => {
|
||||
const [isRtl, setIsRtl] = useRTL()
|
||||
const themeColors = useContext(ThemeColors)
|
||||
return (
|
||||
<Fragment>
|
||||
<ExtensionsHeader
|
||||
title='React Rating'
|
||||
subTitle='A rating react component with custom symbols'
|
||||
link='https://github.com/dreyescat/react-rating'
|
||||
/>
|
||||
<Row className='match-height'>
|
||||
<Col lg={6} xs={12}>
|
||||
<RatingBasic dir={isRtl ? 'rtl' : 'ltr'} filledColor={themeColors.colors.warning.main} />
|
||||
</Col>
|
||||
<Col lg={6} xs={12}>
|
||||
<RatingReadOnly dir={isRtl ? 'rtl' : 'ltr'} filledColor={themeColors.colors.warning.main} />
|
||||
</Col>
|
||||
<Col lg={6} xs={12}>
|
||||
<RatingFractional dir={isRtl ? 'rtl' : 'ltr'} filledColor={themeColors.colors.warning.main} />
|
||||
</Col>
|
||||
<Col lg={6} xs={12}>
|
||||
<RatingCustomSvg dir={isRtl ? 'rtl' : 'ltr'} filledColor={themeColors.colors.warning.main} />
|
||||
</Col>
|
||||
<Col lg={6} xs={12}>
|
||||
<RatingNumbers dir={isRtl ? 'rtl' : 'ltr'} filledColor={themeColors.colors.warning.main} />
|
||||
</Col>
|
||||
<Col lg={6} xs={12}>
|
||||
<RatingEvents dir={isRtl ? 'rtl' : 'ltr'} filledColor={themeColors.colors.warning.main} />
|
||||
</Col>
|
||||
<Col lg={6} xs={12}>
|
||||
<RatingControlled dir={isRtl ? 'rtl' : 'ltr'} filledColor={themeColors.colors.warning.main} />
|
||||
</Col>
|
||||
<Col lg={6} xs={12}>
|
||||
<RatingSizes dir={isRtl ? 'rtl' : 'ltr'} filledColor={themeColors.colors.warning.main} />
|
||||
</Col>
|
||||
</Row>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default Rating
|
@ -1,186 +0,0 @@
|
||||
import { useState, useEffect, useRef } from 'react'
|
||||
import { Card, CardTitle, CardHeader, CardBody, Row, Col, Table, Button, Progress, CustomInput } from 'reactstrap'
|
||||
import Prism from 'prismjs'
|
||||
import ReactPlayer from 'react-player'
|
||||
|
||||
const pad = string => {
|
||||
return `0${string}`.slice(-2)
|
||||
}
|
||||
const format = seconds => {
|
||||
const date = new Date(seconds * 1000)
|
||||
const hh = date.getUTCHours()
|
||||
const mm = date.getUTCMinutes()
|
||||
const ss = pad(date.getUTCSeconds())
|
||||
if (hh) {
|
||||
return `${hh}:${pad(mm)}:${ss}`
|
||||
}
|
||||
return `${mm}:${ss}`
|
||||
}
|
||||
|
||||
const MediaPlayerAudio = () => {
|
||||
useEffect(() => {
|
||||
Prism.highlightAll()
|
||||
})
|
||||
|
||||
const audioRef = useRef(null)
|
||||
|
||||
const urlLink = 'https://soundcloud.com/2ghost/we-will-rock-you'
|
||||
const [url, setUrl] = useState(urlLink)
|
||||
const [playing, setPlaying] = useState(false)
|
||||
const [volume, setVolume] = useState(0.75)
|
||||
const [muted, setMuted] = useState(false)
|
||||
const [played, setPlayed] = useState(0)
|
||||
const [loaded, setLoaded] = useState(0)
|
||||
const [duration, setDuration] = useState(0)
|
||||
const [seeking, setSeeking] = useState(null)
|
||||
|
||||
const load = url => {
|
||||
setUrl(url)
|
||||
setPlayed(0)
|
||||
setLoaded(0)
|
||||
}
|
||||
const handlePlayPause = () => setPlaying(!playing)
|
||||
const handleStop = () => {
|
||||
setPlaying(false)
|
||||
setUrl(null)
|
||||
}
|
||||
const handleVolumeChange = e => setVolume(parseFloat(e.target.value))
|
||||
const handleToggleMuted = () => setMuted(!muted)
|
||||
const handlePlay = () => setPlaying(true)
|
||||
const handlePause = () => setPlaying(false)
|
||||
const handleSeekMouseDown = () => setSeeking(true)
|
||||
const handleSeekChange = e => {
|
||||
setPlayed(parseFloat(e.target.value))
|
||||
}
|
||||
const handleSeekMouseUp = e => {
|
||||
setSeeking(false)
|
||||
audioRef.current.seekTo(parseFloat(e.target.value))
|
||||
}
|
||||
const handleProgress = state => {
|
||||
if (!seeking) {
|
||||
setPlayed(state.played)
|
||||
setLoaded(state.loaded)
|
||||
}
|
||||
}
|
||||
const handleDuration = duration => setDuration(duration)
|
||||
useEffect(() => {
|
||||
if (url === null) {
|
||||
load(urlLink)
|
||||
}
|
||||
})
|
||||
|
||||
// for duration, elapsed and remaining time
|
||||
const Duration = ({ className, seconds }) => {
|
||||
return (
|
||||
<time dateTime={`P${Math.round(seconds)}S`} className={className}>
|
||||
{format(seconds)}
|
||||
</time>
|
||||
)
|
||||
}
|
||||
const preDuration = <Duration seconds={duration}></Duration>
|
||||
const preElapsed = <Duration seconds={duration * played}></Duration>
|
||||
const preRemaining = <Duration seconds={duration * (1 - played)}></Duration>
|
||||
|
||||
return (
|
||||
<Card className='overflow-hidden'>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Audio</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
<ReactPlayer
|
||||
ref={audioRef}
|
||||
url={url}
|
||||
className='react-player-audio'
|
||||
width='500px'
|
||||
height='290px'
|
||||
playing={playing}
|
||||
volume={volume}
|
||||
muted={muted}
|
||||
onPlay={handlePlay}
|
||||
onPause={handlePause}
|
||||
onSeek={e => console.log('onSeek', e)}
|
||||
onProgress={handleProgress}
|
||||
onDuration={handleDuration}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs={12}>
|
||||
<Table borderless className='mt-2'>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className='text-right'>Controls</td>
|
||||
<td>
|
||||
<Button variant='primary' outline onClick={handleStop} className='my-25 mr-50'>
|
||||
Stop
|
||||
</Button>
|
||||
<Button variant='primary' outline onClick={handlePlayPause} className='my-25'>
|
||||
{playing ? 'Pause' : 'Play'}
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='text-right'>Seek</td>
|
||||
<td>
|
||||
<input
|
||||
type='range'
|
||||
min={0}
|
||||
max={0.999999}
|
||||
step='any'
|
||||
value={played}
|
||||
onMouseDown={handleSeekMouseDown}
|
||||
onChange={handleSeekChange}
|
||||
onMouseUp={handleSeekMouseUp}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='text-right'>Volume</td>
|
||||
<td>
|
||||
<input type='range' min={0} max={1} step='any' value={volume} onChange={handleVolumeChange} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='text-right'>Muted</td>
|
||||
<td>
|
||||
<CustomInput type='checkbox' id='audioMuted' checked={muted} onChange={handleToggleMuted} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='text-right'>Played</td>
|
||||
<td>
|
||||
<Progress value={played} max={1} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='text-right'>Loaded</td>
|
||||
<td>
|
||||
<Progress value={loaded} max={1} />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</Table>
|
||||
</Col>
|
||||
<Col xs={12}>
|
||||
<pre className='language-js'>
|
||||
<code className='language-js'>
|
||||
{`state={
|
||||
playing: ${playing},
|
||||
volume: ${volume.toFixed(2)},
|
||||
played: ${played.toFixed(2)},
|
||||
loaded: ${loaded.toFixed(2)},
|
||||
duration: ${format(preDuration.props.seconds)},
|
||||
elapsed: ${format(preElapsed.props.seconds)},
|
||||
remaining: ${format(preRemaining.props.seconds)}
|
||||
}
|
||||
`}
|
||||
</code>
|
||||
</pre>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default MediaPlayerAudio
|
@ -1,256 +0,0 @@
|
||||
import { useState, useEffect, useRef } from 'react'
|
||||
import { findDOMNode } from 'react-dom'
|
||||
import { Card, CardTitle, CardHeader, CardBody, Row, Col, Table, Button, Progress, CustomInput } from 'reactstrap'
|
||||
import Prism from 'prismjs'
|
||||
import ReactPlayer from 'react-player'
|
||||
import screenfull from 'screenfull'
|
||||
|
||||
const pad = string => {
|
||||
return `0${string}`.slice(-2)
|
||||
}
|
||||
const format = seconds => {
|
||||
const date = new Date(seconds * 1000)
|
||||
const hh = date.getUTCHours()
|
||||
const mm = date.getUTCMinutes()
|
||||
const ss = pad(date.getUTCSeconds())
|
||||
if (hh) {
|
||||
return `${hh}:${pad(mm)}:${ss}`
|
||||
}
|
||||
return `${mm}:${ss}`
|
||||
}
|
||||
|
||||
const MediaPlayerControlledVideo = () => {
|
||||
useEffect(() => {
|
||||
Prism.highlightAll()
|
||||
})
|
||||
|
||||
const videoRef = useRef(null)
|
||||
|
||||
const urlLink = 'http://youtube.com/watch?v=FCPdIvXo2rU'
|
||||
const [url, setUrl] = useState(urlLink)
|
||||
const [playing, setPlaying] = useState(false)
|
||||
const [controls, setControls] = useState(false)
|
||||
const [volume, setVolume] = useState(0.75)
|
||||
const [muted, setMuted] = useState(false)
|
||||
const [played, setPlayed] = useState(0)
|
||||
const [loaded, setLoaded] = useState(0)
|
||||
const [duration, setDuration] = useState(0)
|
||||
const [playbackRate, setPlaybackRate] = useState(1.0)
|
||||
const [loop, setLoop] = useState(false)
|
||||
const [seeking, setSeeking] = useState(null)
|
||||
|
||||
const load = url => {
|
||||
setUrl(url)
|
||||
setPlayed(0)
|
||||
setLoaded(0)
|
||||
}
|
||||
const handlePlayPause = () => setPlaying(!playing)
|
||||
const handleStop = () => {
|
||||
setPlaying(false)
|
||||
setUrl(null)
|
||||
}
|
||||
const handleToggleControls = () => {
|
||||
setControls(!controls)
|
||||
setUrl(null)
|
||||
}
|
||||
useEffect(() => {
|
||||
if (url === null) {
|
||||
load(urlLink)
|
||||
}
|
||||
})
|
||||
const handleToggleLoop = () => setLoop(!loop)
|
||||
const handleVolumeChange = e => setVolume(parseFloat(e.target.value))
|
||||
const handleToggleMuted = () => setMuted(!muted)
|
||||
const handlePlaybackRate = e => setPlaybackRate(parseFloat(e.target.value))
|
||||
const handlePlay = () => setPlaying(true)
|
||||
const handlePause = () => setPlaying(false)
|
||||
const handleSeekMouseDown = () => setSeeking(true)
|
||||
const handleSeekChange = e => {
|
||||
setPlayed(parseFloat(e.target.value))
|
||||
}
|
||||
const handleSeekMouseUp = e => {
|
||||
setSeeking(false)
|
||||
videoRef.current.seekTo(parseFloat(e.target.value))
|
||||
}
|
||||
const handleProgress = state => {
|
||||
if (!seeking) {
|
||||
setPlayed(state.played)
|
||||
setLoaded(state.loaded)
|
||||
}
|
||||
}
|
||||
const handleEnded = () => setPlaying(loop)
|
||||
const handleDuration = duration => setDuration(duration)
|
||||
const handleFullscreen = () => {
|
||||
screenfull.request(findDOMNode(videoRef.current))
|
||||
}
|
||||
|
||||
// for duration, elapsed and remaining time
|
||||
const Duration = ({ className, seconds }) => {
|
||||
return (
|
||||
<time dateTime={`P${Math.round(seconds)}S`} className={className}>
|
||||
{format(seconds)}
|
||||
</time>
|
||||
)
|
||||
}
|
||||
const preDuration = <Duration seconds={duration}></Duration>
|
||||
const preElapsed = <Duration seconds={duration * played}></Duration>
|
||||
const preRemaining = <Duration seconds={duration * (1 - played)}></Duration>
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Controlled Video</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
<ReactPlayer
|
||||
ref={videoRef}
|
||||
url={url}
|
||||
className='react-player-video'
|
||||
width='100%'
|
||||
playing={playing}
|
||||
controls={controls}
|
||||
loop={loop}
|
||||
playbackRate={playbackRate}
|
||||
volume={volume}
|
||||
muted={muted}
|
||||
onPlay={handlePlay}
|
||||
onPause={handlePause}
|
||||
onEnded={handleEnded}
|
||||
onProgress={handleProgress}
|
||||
onDuration={handleDuration}
|
||||
config={{
|
||||
youtube: {
|
||||
embedOptions: {
|
||||
'allow-same-origin': true
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
<Table borderless>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className='text-right'>Controls</td>
|
||||
<td>
|
||||
<Button color='primary' outline onClick={handleStop} className='my-25 mr-50'>
|
||||
Stop
|
||||
</Button>
|
||||
<Button color='primary' outline onClick={handlePlayPause} className='my-25 mr-50'>
|
||||
{playing ? 'Pause' : 'Play'}
|
||||
</Button>
|
||||
<Button color='primary' outline onClick={handleFullscreen} className='my-25'>
|
||||
Fullscreen
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='text-right'>Speed</td>
|
||||
<td>
|
||||
<Button
|
||||
color='primary'
|
||||
outline
|
||||
onClick={handlePlaybackRate}
|
||||
value={1}
|
||||
className='my-25 mr-50'
|
||||
active={playbackRate === 1}
|
||||
>
|
||||
1x
|
||||
</Button>
|
||||
<Button
|
||||
color='primary'
|
||||
outline
|
||||
onClick={handlePlaybackRate}
|
||||
value={1.5}
|
||||
className='my-25 mr-50'
|
||||
active={playbackRate === 1.5}
|
||||
>
|
||||
1.5x
|
||||
</Button>
|
||||
<Button color='primary' outline onClick={handlePlaybackRate} value={2} active={playbackRate === 2}>
|
||||
2x
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='text-right'>Seek</td>
|
||||
<td>
|
||||
<input
|
||||
type='range'
|
||||
min={0}
|
||||
max={0.999999}
|
||||
step='any'
|
||||
value={played}
|
||||
onMouseDown={handleSeekMouseDown}
|
||||
onChange={handleSeekChange}
|
||||
onMouseUp={handleSeekMouseUp}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='text-right'>Volume</td>
|
||||
<td>
|
||||
<input type='range' min={0} max={1} step='any' value={volume} onChange={handleVolumeChange} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='text-right'>Controls</td>
|
||||
<td>
|
||||
<CustomInput type='checkbox' id='videoControls' checked={controls} onChange={handleToggleControls} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='text-right'>Muted</td>
|
||||
<td>
|
||||
<CustomInput type='checkbox' id='videoMuted' checked={muted} onChange={handleToggleMuted} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='text-right'>Loop</td>
|
||||
<td>
|
||||
<CustomInput type='checkbox' id='videoLoop' checked={loop} onChange={handleToggleLoop} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='text-right'>Played</td>
|
||||
<td>
|
||||
<Progress value={played} max={1} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='text-right'>Loaded</td>
|
||||
<td>
|
||||
<Progress value={loaded} max={1} />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</Table>
|
||||
|
||||
<CardBody>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
<pre className='language-js'>
|
||||
<code className='language-js'>
|
||||
{`state={
|
||||
playing: ${playing},
|
||||
volume: ${volume.toFixed(2)},
|
||||
played: ${played.toFixed(2)},
|
||||
loaded: ${loaded.toFixed(2)},
|
||||
duration: ${format(preDuration.props.seconds)},
|
||||
elapsed: ${format(preElapsed.props.seconds)},
|
||||
remaining: ${format(preRemaining.props.seconds)}
|
||||
}
|
||||
`}
|
||||
</code>
|
||||
</pre>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default MediaPlayerControlledVideo
|
@ -1,22 +0,0 @@
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import ReactPlayer from 'react-player'
|
||||
|
||||
const MediaPlayerVideo = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Video</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<ReactPlayer
|
||||
url='http://youtube.com/watch?v=FCPdIvXo2rU'
|
||||
className='react-player-video'
|
||||
width='100%'
|
||||
controls={true}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default MediaPlayerVideo
|
31
src/views/extensions/react-player/index.js
vendored
31
src/views/extensions/react-player/index.js
vendored
@ -1,31 +0,0 @@
|
||||
import { Fragment } from 'react'
|
||||
import { Row, Col } from 'reactstrap'
|
||||
import MediaPlayerVideo from './MediaPlayerVideo'
|
||||
import MediaPlayerAudio from './MediaPlayerAudio'
|
||||
import MediaPlayerControlled from './MediaPlayerControlled'
|
||||
import ExtensionsHeader from '@components/extensions-header'
|
||||
|
||||
const ReactPlayer = () => {
|
||||
return (
|
||||
<Fragment>
|
||||
<ExtensionsHeader
|
||||
title='React Player'
|
||||
subTitle='React Media Player'
|
||||
link='https://github.com/CookPete/react-player'
|
||||
/>
|
||||
<Row>
|
||||
<Col sm='12'>
|
||||
<MediaPlayerVideo />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<MediaPlayerControlled />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<MediaPlayerAudio />
|
||||
</Col>
|
||||
</Row>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default ReactPlayer
|
@ -1,60 +0,0 @@
|
||||
import Nouislider from 'nouislider-react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
|
||||
const SliderBehaviour = ({ direction }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Slider Behaviour</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<h5 className='mb-2'>Tap</h5>
|
||||
<Nouislider
|
||||
start={[20, 40]}
|
||||
direction={direction}
|
||||
behaviour={'tap'}
|
||||
connect={true}
|
||||
range={{
|
||||
min: 10,
|
||||
max: 50
|
||||
}}
|
||||
/>
|
||||
<h5 className='my-2'>Drag</h5>
|
||||
<Nouislider
|
||||
start={[40, 60]}
|
||||
direction={direction}
|
||||
behaviour={'drag'}
|
||||
connect={true}
|
||||
range={{
|
||||
min: 20,
|
||||
max: 80
|
||||
}}
|
||||
/>
|
||||
<h5 className='my-2'>Fixed dragging</h5>
|
||||
<Nouislider
|
||||
start={[40, 60]}
|
||||
direction={direction}
|
||||
behaviour={'drag-fixed'}
|
||||
connect={true}
|
||||
range={{
|
||||
min: 20,
|
||||
max: 80
|
||||
}}
|
||||
/>
|
||||
<h5 className='my-2'>Combined options</h5>
|
||||
<Nouislider
|
||||
start={[40, 60]}
|
||||
direction={direction}
|
||||
behaviour={'drag-tap'}
|
||||
connect={true}
|
||||
range={{
|
||||
min: 20,
|
||||
max: 80
|
||||
}}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SliderBehaviour
|
@ -1,51 +0,0 @@
|
||||
import Nouislider from 'nouislider-react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
|
||||
const SliderValues = ({ direction }) => {
|
||||
const colorOptions = {
|
||||
start: [40, 60],
|
||||
connect: true,
|
||||
behaviour: 'drag',
|
||||
step: 10,
|
||||
tooltips: true,
|
||||
range: {
|
||||
min: 0,
|
||||
max: 100
|
||||
},
|
||||
pips: {
|
||||
mode: 'steps',
|
||||
stepped: true,
|
||||
density: 5
|
||||
},
|
||||
direction
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Colors</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<h5 className='my-2'>Default / Primary Color Slider</h5>
|
||||
<Nouislider className='mt-md-1 mt-3 mb-4' {...colorOptions} />
|
||||
|
||||
<h5 className='my-2'>Secondary Color Slider</h5>
|
||||
<Nouislider className='slider-secondary mt-md-1 mt-3 mb-4' {...colorOptions} />
|
||||
|
||||
<h5 className='my-2'>Success Color Slider</h5>
|
||||
<Nouislider className='slider-success mt-md-1 mt-3 mb-4' {...colorOptions} />
|
||||
|
||||
<h5 className='my-2'>Danger Color Slider</h5>
|
||||
<Nouislider className='slider-danger mt-md-1 mt-3 mb-4' {...colorOptions} />
|
||||
|
||||
<h5 className='my-2'>warning Color Slider</h5>
|
||||
<Nouislider className='slider-warning mt-md-1 mt-3 mb-4' {...colorOptions} />
|
||||
|
||||
<h5 className='my-2'>info Color Slider</h5>
|
||||
<Nouislider className='slider-info mt-md-1 mt-3 mb-4' {...colorOptions} />
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SliderValues
|
@ -1,29 +0,0 @@
|
||||
import Nouislider from 'nouislider-react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
|
||||
const SliderConnectUpper = ({ direction }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Connect to upper</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody className='text-center'>
|
||||
<Nouislider
|
||||
connect='upper'
|
||||
start={30}
|
||||
direction={direction}
|
||||
orientation='vertical'
|
||||
range={{
|
||||
min: 0,
|
||||
max: 100
|
||||
}}
|
||||
style={{
|
||||
height: '200px'
|
||||
}}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SliderConnectUpper
|
@ -1,32 +0,0 @@
|
||||
import Nouislider from 'nouislider-react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
|
||||
const SliderScalePips = ({ direction }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Slider Scales / Pips</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Nouislider
|
||||
className='mt-1 mb-3'
|
||||
start={10}
|
||||
step={10}
|
||||
tooltips={true}
|
||||
direction={direction}
|
||||
range={{
|
||||
min: 0,
|
||||
max: 100
|
||||
}}
|
||||
pips={{
|
||||
mode: 'steps',
|
||||
stepped: true,
|
||||
density: 5
|
||||
}}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SliderScalePips
|
@ -1,34 +0,0 @@
|
||||
import Nouislider from 'nouislider-react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
|
||||
const SliderValues = ({ direction }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Slider Values</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<h5 className='mb-2'>Handles</h5>
|
||||
<Nouislider start={[4000, 8000]} direction={direction} range={{ min: [2000], max: [10000] }} />
|
||||
<h5 className='my-2'>Snapping between steps</h5>
|
||||
<Nouislider
|
||||
start={[0, 500]}
|
||||
direction={direction}
|
||||
snap={true}
|
||||
connect={true}
|
||||
range={{
|
||||
min: 0,
|
||||
'10%': 50,
|
||||
'20%': 100,
|
||||
'30%': 150,
|
||||
'40%': 500,
|
||||
'50%': 800,
|
||||
max: 1000
|
||||
}}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SliderValues
|
@ -1,28 +0,0 @@
|
||||
import Nouislider from 'nouislider-react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
|
||||
const SliderVertical = ({ direction }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Vertical Default</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody className='text-center'>
|
||||
<Nouislider
|
||||
start={20}
|
||||
direction={direction}
|
||||
orientation='vertical'
|
||||
range={{
|
||||
min: 0,
|
||||
max: 100
|
||||
}}
|
||||
style={{
|
||||
height: '200px'
|
||||
}}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SliderVertical
|
@ -1,31 +0,0 @@
|
||||
import Nouislider from 'nouislider-react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
|
||||
const SliderLimit = ({ direction }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Limit</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody className='text-center'>
|
||||
<Nouislider
|
||||
start={[40, 60]}
|
||||
direction={direction}
|
||||
orientation={'vertical'}
|
||||
limit={40}
|
||||
behaviour={'drag'}
|
||||
connect={true}
|
||||
range={{
|
||||
min: 0,
|
||||
max: 100
|
||||
}}
|
||||
style={{
|
||||
height: '200px'
|
||||
}}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SliderLimit
|
@ -1,37 +0,0 @@
|
||||
import Nouislider from 'nouislider-react'
|
||||
import wNumb from 'wnumb'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
|
||||
const SliderTooltips = ({ direction }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Tooltips</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody className='text-center'>
|
||||
<Nouislider
|
||||
start={[20, 80]}
|
||||
direction={direction}
|
||||
orientation={'vertical'}
|
||||
tooltips={[
|
||||
wNumb({
|
||||
decimals: 1
|
||||
}),
|
||||
wNumb({
|
||||
decimals: 1
|
||||
})
|
||||
]}
|
||||
range={{
|
||||
min: 0,
|
||||
max: 100
|
||||
}}
|
||||
style={{
|
||||
height: '200px'
|
||||
}}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SliderTooltips
|
@ -1,178 +0,0 @@
|
||||
import { useState } from 'react'
|
||||
import Nouislider from 'nouislider-react'
|
||||
import { Card, CardHeader, CardTitle, CardBody, Input, Row, Col } from 'reactstrap'
|
||||
|
||||
const SliderWithInput = ({ direction }) => {
|
||||
const [upperConnect, setUpperConnect] = useState(10)
|
||||
const [lowerConnect, setLowerConnect] = useState(30.0)
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Slider With Input</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Nouislider
|
||||
className='my-1'
|
||||
start={[upperConnect, lowerConnect]}
|
||||
direction={direction}
|
||||
connect={true}
|
||||
range={{
|
||||
min: -20,
|
||||
max: 40
|
||||
}}
|
||||
/>
|
||||
<Row>
|
||||
<Col md='3' sm='12' className='d-sm-flex d-block'>
|
||||
<Input
|
||||
className='mr-1 mt-2'
|
||||
type='select'
|
||||
name='selectUpper'
|
||||
value={upperConnect}
|
||||
onChange={e => setUpperConnect(e.target.value)}
|
||||
>
|
||||
<option value='-20'> -20 </option>
|
||||
<option value='-19'> -19 </option>
|
||||
<option value='-18'> -18 </option>
|
||||
<option value='-17'> -17 </option>
|
||||
<option value='-16'> -16 </option>
|
||||
<option value='-15'> -15 </option>
|
||||
<option value='-14'> -14 </option>
|
||||
<option value='-13'> -13 </option>
|
||||
<option value='-12'> -12 </option>
|
||||
<option value='-11'> -11 </option>
|
||||
<option value='-10'> -10 </option>
|
||||
<option value='-9'> -9 </option>
|
||||
<option value='-8'> -8 </option>
|
||||
<option value='-7'> -7 </option>
|
||||
<option value='-6'> -6 </option>
|
||||
<option value='-5'> -5 </option>
|
||||
<option value='-4'> -4 </option>
|
||||
<option value='-3'> -3 </option>
|
||||
<option value='-2'> -2 </option>
|
||||
<option value='-1'> -1 </option>
|
||||
<option value='0'>0</option>
|
||||
<option value='1'>1</option>
|
||||
<option value='2'>2</option>
|
||||
<option value='3'>3</option>
|
||||
<option value='4'>4</option>
|
||||
<option value='5'>5</option>
|
||||
<option value='6'>6</option>
|
||||
<option value='7'>7</option>
|
||||
<option value='8'>8</option>
|
||||
<option value='9'>9</option>
|
||||
<option value='10'>10</option>
|
||||
<option value='11'>11</option>
|
||||
<option value='12'>12</option>
|
||||
<option value='13'>13</option>
|
||||
<option value='14'>14</option>
|
||||
<option value='15'>15</option>
|
||||
<option value='16'>16</option>
|
||||
<option value='17'>17</option>
|
||||
<option value='18'>18</option>
|
||||
<option value='19'>19</option>
|
||||
<option value='20'>20</option>
|
||||
<option value='21'>21</option>
|
||||
<option value='22'>22</option>
|
||||
<option value='23'>23</option>
|
||||
<option value='24'>24</option>
|
||||
<option value='25'>25</option>
|
||||
<option value='26'>26</option>
|
||||
<option value='27'>27</option>
|
||||
<option value='28'>28</option>
|
||||
<option value='29'>29</option>
|
||||
<option value='30'>30</option>
|
||||
<option value='31'>31</option>
|
||||
<option value='32'>32</option>
|
||||
<option value='33'>33</option>
|
||||
<option value='34'>34</option>
|
||||
<option value='35'>35</option>
|
||||
<option value='36'>36</option>
|
||||
<option value='37'>37</option>
|
||||
<option value='38'>38</option>
|
||||
<option value='39'>39</option>
|
||||
<option value='40'>40</option>
|
||||
<option value='-20'> -20 </option>
|
||||
<option value='-19'> -19 </option>
|
||||
<option value='-18'> -18 </option>
|
||||
<option value='-17'> -17 </option>
|
||||
<option value='-16'> -16 </option>
|
||||
<option value='-15'> -15 </option>
|
||||
<option value='-14'> -14 </option>
|
||||
<option value='-13'> -13 </option>
|
||||
<option value='-12'> -12 </option>
|
||||
<option value='-11'> -11 </option>
|
||||
<option value='-10'> -10 </option>
|
||||
<option value='-9'> -9 </option>
|
||||
<option value='-8'> -8 </option>
|
||||
<option value='-7'> -7 </option>
|
||||
<option value='-6'> -6 </option>
|
||||
<option value='-5'> -5 </option>
|
||||
<option value='-4'> -4 </option>
|
||||
<option value='-3'> -3 </option>
|
||||
<option value='-2'> -2 </option>
|
||||
<option value='-1'> -1 </option>
|
||||
<option value='0'>0</option>
|
||||
<option value='1'>1</option>
|
||||
<option value='2'>2</option>
|
||||
<option value='3'>3</option>
|
||||
<option value='4'>4</option>
|
||||
<option value='5'>5</option>
|
||||
<option value='6'>6</option>
|
||||
<option value='7'>7</option>
|
||||
<option value='8'>8</option>
|
||||
<option value='9'>9</option>
|
||||
<option value='10'>10</option>
|
||||
<option value='11'>11</option>
|
||||
<option value='12'>12</option>
|
||||
<option value='13'>13</option>
|
||||
<option value='14'>14</option>
|
||||
<option value='15'>15</option>
|
||||
<option value='16'>16</option>
|
||||
<option value='17'>17</option>
|
||||
<option value='18'>18</option>
|
||||
<option value='19'>19</option>
|
||||
<option value='20'>20</option>
|
||||
<option value='21'>21</option>
|
||||
<option value='22'>22</option>
|
||||
<option value='23'>23</option>
|
||||
<option value='24'>24</option>
|
||||
<option value='25'>25</option>
|
||||
<option value='26'>26</option>
|
||||
<option value='27'>27</option>
|
||||
<option value='28'>28</option>
|
||||
<option value='29'>29</option>
|
||||
<option value='30'>30</option>
|
||||
<option value='31'>31</option>
|
||||
<option value='32'>32</option>
|
||||
<option value='33'>33</option>
|
||||
<option value='34'>34</option>
|
||||
<option value='35'>35</option>
|
||||
<option value='36'>36</option>
|
||||
<option value='37'>37</option>
|
||||
<option value='38'>38</option>
|
||||
<option value='39'>39</option>
|
||||
<option value='40'>40</option>
|
||||
<option>1</option>
|
||||
<option>2</option>
|
||||
<option>3</option>
|
||||
<option>4</option>
|
||||
<option>5</option>
|
||||
</Input>
|
||||
<Input
|
||||
type='number'
|
||||
className='mt-2'
|
||||
min='-20'
|
||||
max='40'
|
||||
step='1'
|
||||
value={lowerConnect}
|
||||
onChange={e => setLowerConnect(e.target.value)}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SliderWithInput
|
@ -1,23 +0,0 @@
|
||||
import { Card, CardHeader, CardTitle, CardBody, FormGroup, Input, Label } from 'reactstrap'
|
||||
|
||||
const SlidersBootstrap = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Default Bootstrap 4 slider</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<FormGroup>
|
||||
<Label for='default-range'>Default</Label>
|
||||
<Input type='range' name='default-range' id='default-range' />
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for='disable-range'>Disabled</Label>
|
||||
<Input type='range' name='disable-range' id='disable-range' disabled />
|
||||
</FormGroup>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SlidersBootstrap
|
@ -1,67 +0,0 @@
|
||||
import { Fragment } from 'react'
|
||||
import { Row, Col } from 'reactstrap'
|
||||
import { useRTL } from '@hooks/useRTL'
|
||||
import SliderColors from './SliderColors'
|
||||
import SliderValues from './SliderValues'
|
||||
import SliderVertical from './SliderVertical'
|
||||
import SliderBehaviour from './SliderBehaviour'
|
||||
import SliderScalePips from './SliderScalePips'
|
||||
import SliderWithInput from './SliderWithInput'
|
||||
import SliderBootstrap from './SlidersBootstrap'
|
||||
import SliderConnectUpper from './SliderConnectUpper'
|
||||
import SliderVerticalLimit from './SliderVerticalLimit'
|
||||
import SliderVerticalTooltip from './SliderVerticalTooltips'
|
||||
import ExtensionsHeader from '@components/extensions-header'
|
||||
|
||||
import '@styles/react/libs/noui-slider/noui-slider.scss'
|
||||
|
||||
const Slider = () => {
|
||||
const [isRtl, setIsRtl] = useRTL()
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<ExtensionsHeader
|
||||
title='Noui Slider'
|
||||
subTitle='noUiSlider is a lightweight JavaScript range slider.'
|
||||
link='https://github.com/mmarkelov/react-nouislider'
|
||||
/>
|
||||
|
||||
<Row>
|
||||
<Col sm='12'>
|
||||
<SliderBootstrap />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<SliderValues direction={isRtl === true ? 'rtl' : 'ltr'} />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<SliderBehaviour direction={isRtl === true ? 'rtl' : 'ltr'} />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<SliderScalePips direction={isRtl === true ? 'rtl' : 'ltr'} />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<SliderColors direction={isRtl === true ? 'rtl' : 'ltr'} />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<SliderWithInput direction={isRtl === true ? 'rtl' : 'ltr'} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col lg='3' md='6' sm='12'>
|
||||
<SliderVertical direction={isRtl === true ? 'rtl' : 'ltr'} />
|
||||
</Col>
|
||||
<Col lg='3' md='6' sm='12'>
|
||||
<SliderConnectUpper direction={isRtl === true ? 'rtl' : 'ltr'} />
|
||||
</Col>
|
||||
<Col lg='3' md='6' sm='12'>
|
||||
<SliderVerticalTooltip direction={isRtl === true ? 'rtl' : 'ltr'} />
|
||||
</Col>
|
||||
<Col lg='3' md='6' sm='12'>
|
||||
<SliderVerticalLimit direction={isRtl === true ? 'rtl' : 'ltr'} />
|
||||
</Col>
|
||||
</Row>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default Slider
|
@ -1,104 +0,0 @@
|
||||
import Swal from 'sweetalert2'
|
||||
import withReactContent from 'sweetalert2-react-content'
|
||||
import { Card, CardHeader, CardBody, CardTitle, Button, CardText } from 'reactstrap'
|
||||
|
||||
const MySwal = withReactContent(Swal)
|
||||
|
||||
const AnimatedSweetAlert = () => {
|
||||
const handleBounceIn = () => {
|
||||
return MySwal.fire({
|
||||
title: 'Bounce In Animation',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
},
|
||||
showClass: {
|
||||
popup: 'animate__animated animate__bounceIn'
|
||||
},
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
const handleFadeIn = () => {
|
||||
return MySwal.fire({
|
||||
title: 'Fade In Animation',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
},
|
||||
showClass: {
|
||||
popup: 'animate__animated animate__fadeIn'
|
||||
},
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
const handleFlipIn = () => {
|
||||
return MySwal.fire({
|
||||
title: 'Flip In Animation',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
},
|
||||
showClass: {
|
||||
popup: 'animate__animated animate__flipInX'
|
||||
},
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
const handleTada = () => {
|
||||
return MySwal.fire({
|
||||
title: 'Tada Animation',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
},
|
||||
showClass: {
|
||||
popup: 'animate__animated animate__tada'
|
||||
},
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
const handleShake = () => {
|
||||
return MySwal.fire({
|
||||
title: 'Shake Animation',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
},
|
||||
showClass: {
|
||||
popup: 'animate__animated animate__shakeX'
|
||||
},
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Animations</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<CardText className='mb-0'>
|
||||
Use <code>popup</code> inside <code>showClass</code> parameter to add animation to your alert.
|
||||
</CardText>
|
||||
<div className='demo-inline-spacing'>
|
||||
<Button color='primary' onClick={handleBounceIn} outline>
|
||||
Bounce In
|
||||
</Button>
|
||||
<Button color='primary' onClick={handleFadeIn} outline>
|
||||
Fade In
|
||||
</Button>
|
||||
<Button color='primary' onClick={handleFlipIn} outline>
|
||||
Flip In
|
||||
</Button>
|
||||
<Button color='primary' onClick={handleTada} outline>
|
||||
Tada
|
||||
</Button>
|
||||
<Button color='primary' onClick={handleShake} outline>
|
||||
Shake
|
||||
</Button>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default AnimatedSweetAlert
|
@ -1,98 +0,0 @@
|
||||
import Swal from 'sweetalert2'
|
||||
import { ThumbsUp, ThumbsDown } from 'react-feather'
|
||||
import withReactContent from 'sweetalert2-react-content'
|
||||
import { Card, CardHeader, CardBody, CardTitle, Button, CardText } from 'reactstrap'
|
||||
|
||||
const MySwal = withReactContent(Swal)
|
||||
|
||||
const BasicSweetAlert = () => {
|
||||
const handleBasicTitleAlert = () => {
|
||||
return MySwal.fire({
|
||||
title: 'Any fool can use a computer',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
},
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
const handleTitleAlert = () => {
|
||||
return MySwal.fire({
|
||||
title: 'The Internet?,',
|
||||
text: 'That thing is still around?',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
},
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
const handleFooterAlert = () => {
|
||||
return MySwal.fire({
|
||||
icon: 'error',
|
||||
title: 'Oops...',
|
||||
text: 'Something went wrong!',
|
||||
footer: '<a href="javascript:void(0);">Why do I have this issue?</a>',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
},
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
const handleHTMLAlert = () => {
|
||||
return MySwal.fire({
|
||||
title: '<strong>HTML <u>example</u></strong>',
|
||||
icon: 'info',
|
||||
html:
|
||||
'You can use <b>bold text</b>, ' +
|
||||
'<a href="https://pixinvent.com/" target="_blank">links</a> ' +
|
||||
'and other HTML tags',
|
||||
showCloseButton: true,
|
||||
showCancelButton: true,
|
||||
focusConfirm: false,
|
||||
confirmButtonText: (
|
||||
<span className='align-middle'>
|
||||
<ThumbsUp className='mr-50' size={15} />
|
||||
<span className='align-middle'>Great!</span>
|
||||
</span>
|
||||
),
|
||||
cancelButtonText: <ThumbsDown size={15} />,
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary',
|
||||
cancelButton: 'btn btn-outline-danger ml-1'
|
||||
},
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Basic</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<CardText className='mb-0'>
|
||||
SweetAlert automatically centers itself on the page and looks great no matter if you're using a desktop
|
||||
computer, mobile or tablet. It's even highly customizable, as you can see below!
|
||||
</CardText>
|
||||
<div className='demo-inline-spacing'>
|
||||
<Button color='primary' onClick={handleBasicTitleAlert} outline>
|
||||
Basic
|
||||
</Button>
|
||||
<Button color='primary' onClick={handleTitleAlert} outline>
|
||||
With Title
|
||||
</Button>
|
||||
<Button color='primary' onClick={handleFooterAlert} outline>
|
||||
With Footer
|
||||
</Button>
|
||||
<Button color='primary' onClick={handleHTMLAlert} outline>
|
||||
HTML
|
||||
</Button>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default BasicSweetAlert
|
@ -1,95 +0,0 @@
|
||||
import { Card, CardHeader, CardBody, CardTitle, Button, Row, Col } from 'reactstrap'
|
||||
import Swal from 'sweetalert2'
|
||||
import withReactContent from 'sweetalert2-react-content'
|
||||
|
||||
const MySwal = withReactContent(Swal)
|
||||
|
||||
const BasicSweetCallback = () => {
|
||||
const handleConfirmText = () => {
|
||||
return MySwal.fire({
|
||||
title: 'Are you sure?',
|
||||
text: "You won't be able to revert this!",
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Yes, delete it!',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary',
|
||||
cancelButton: 'btn btn-outline-danger ml-1'
|
||||
},
|
||||
buttonsStyling: false
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
MySwal.fire({
|
||||
icon: 'success',
|
||||
title: 'Deleted!',
|
||||
text: 'Your file has been deleted.',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-success'
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleConfirmCancel = () => {
|
||||
return MySwal.fire({
|
||||
title: 'Are you sure?',
|
||||
text: "You won't be able to revert this!",
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Yes, delete it!',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary',
|
||||
cancelButton: 'btn btn-danger ml-1'
|
||||
},
|
||||
buttonsStyling: false
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
MySwal.fire({
|
||||
icon: 'success',
|
||||
title: 'Deleted!',
|
||||
text: 'Your file has been deleted.',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-success'
|
||||
}
|
||||
})
|
||||
} else if (result.dismiss === MySwal.DismissReason.cancel) {
|
||||
MySwal.fire({
|
||||
title: 'Cancelled',
|
||||
text: 'Your imaginary file is safe :)',
|
||||
icon: 'error',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-success'
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Callback</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Row>
|
||||
<Col className='mb-2 mb-md-0' md='6' sm='12'>
|
||||
<h5 className='mb-1'>Confirm Button Text</h5>
|
||||
<Button color='primary' onClick={handleConfirmText} outline>
|
||||
Confirm Text
|
||||
</Button>
|
||||
</Col>
|
||||
|
||||
<Col md='6' sm='12'>
|
||||
<h5 className='mb-1'>Confirm Button Color</h5>
|
||||
<Button color='primary' onClick={handleConfirmCancel} outline>
|
||||
Confirm & cancel
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default BasicSweetCallback
|
@ -1,147 +0,0 @@
|
||||
import { Card, CardHeader, CardBody, CardTitle, Button } from 'reactstrap'
|
||||
import Swal from 'sweetalert2'
|
||||
import withReactContent from 'sweetalert2-react-content'
|
||||
import alertImg from '@src/assets/images/slider/04.jpg'
|
||||
|
||||
const MySwal = withReactContent(Swal)
|
||||
|
||||
const SweetAlertOptions = () => {
|
||||
const handleImageAlert = () => {
|
||||
return MySwal.fire({
|
||||
title: 'Sweet!',
|
||||
text: 'Modal with a custom image.',
|
||||
imageUrl: alertImg,
|
||||
imageWidth: 400,
|
||||
imageHeight: 200,
|
||||
imageAlt: 'Custom image',
|
||||
customClass: { confirmButton: 'btn btn-primary' },
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
const handleTimeoutAlert = () => {
|
||||
let timerInterval
|
||||
Swal.fire({
|
||||
title: 'Auto close alert!',
|
||||
html: 'I will close in <strong></strong> seconds.',
|
||||
timer: 2000,
|
||||
onBeforeOpen() {
|
||||
Swal.showLoading()
|
||||
timerInterval = setInterval(function () {
|
||||
Swal.getContent().querySelector('strong').textContent = Swal.getTimerLeft()
|
||||
}, 100)
|
||||
},
|
||||
onClose() {
|
||||
clearInterval(timerInterval)
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.dismiss === Swal.DismissReason.timer) {
|
||||
console.log('I was closed by the timer')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleClickOutside = () => {
|
||||
return MySwal.fire({
|
||||
title: 'Click outside to close!',
|
||||
text: 'This is a cool message!',
|
||||
allowOutsideClick: true,
|
||||
customClass: { confirmButton: 'btn btn-primary' },
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
const handleQuestions = () => {
|
||||
return MySwal.mixin({
|
||||
input: 'text',
|
||||
confirmButtonText: 'Next →',
|
||||
showCancelButton: true,
|
||||
progressSteps: ['1', '2', '3'],
|
||||
buttonsStyling: false,
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary',
|
||||
cancelButton: 'btn btn-danger ml-1'
|
||||
}
|
||||
})
|
||||
.queue(['Question 1', 'Question 2', 'Question 3'])
|
||||
.then(function (result) {
|
||||
if (result.value) {
|
||||
MySwal.fire({
|
||||
title: 'All done!',
|
||||
html: `Your answers: <pre><code>${JSON.stringify(result.value)}</code></pre>`,
|
||||
confirmButtonText: 'Lovely!',
|
||||
customClass: { confirmButton: 'btn btn-primary' }
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleAjax = () => {
|
||||
MySwal.fire({
|
||||
title: 'Search for a user',
|
||||
input: 'text',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary',
|
||||
cancelButton: 'btn btn-danger ml-1'
|
||||
},
|
||||
buttonsStyling: false,
|
||||
inputAttributes: {
|
||||
autocapitalize: 'off'
|
||||
},
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Look up',
|
||||
showLoaderOnConfirm: true,
|
||||
preConfirm(login) {
|
||||
return fetch(`//api.github.com/users/${login}`)
|
||||
.then(function (response) {
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText)
|
||||
}
|
||||
return response.json()
|
||||
})
|
||||
.catch(function (error) {
|
||||
MySwal.showValidationMessage(`Request failed: ${error}`)
|
||||
})
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
MySwal.fire({
|
||||
title: `${result.value.login}'s avatar`,
|
||||
imageUrl: result.value.avatar_url,
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Options</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<div className='demo-inline-spacing'>
|
||||
<Button color='primary' onClick={handleImageAlert} outline>
|
||||
Image
|
||||
</Button>
|
||||
<Button color='primary' onClick={handleTimeoutAlert} outline>
|
||||
Timeout
|
||||
</Button>
|
||||
<Button color='primary' onClick={handleClickOutside} outline>
|
||||
Click Outside
|
||||
</Button>
|
||||
<Button color='primary' onClick={handleQuestions} outline>
|
||||
Question
|
||||
</Button>
|
||||
<Button color='primary' onClick={handleAjax} outline>
|
||||
Ajax
|
||||
</Button>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SweetAlertOptions
|
@ -1,80 +0,0 @@
|
||||
import { Card, CardHeader, CardBody, CardTitle, Button, CardText } from 'reactstrap'
|
||||
import Swal from 'sweetalert2'
|
||||
import withReactContent from 'sweetalert2-react-content'
|
||||
|
||||
const MySwal = withReactContent(Swal)
|
||||
|
||||
const SweetAlertPositions = () => {
|
||||
const handleTopStart = () => {
|
||||
return MySwal.fire({
|
||||
position: 'top-start',
|
||||
icon: 'success',
|
||||
title: 'Your work has been saved',
|
||||
showConfirmButton: false,
|
||||
timer: 1500
|
||||
})
|
||||
}
|
||||
|
||||
const handleTopEnd = () => {
|
||||
return MySwal.fire({
|
||||
position: 'top-end',
|
||||
icon: 'success',
|
||||
title: 'Your work has been saved',
|
||||
showConfirmButton: false,
|
||||
timer: 1500
|
||||
})
|
||||
}
|
||||
|
||||
const handleBottomStart = () => {
|
||||
return MySwal.fire({
|
||||
position: 'bottom-start',
|
||||
icon: 'success',
|
||||
title: 'Your work has been saved',
|
||||
showConfirmButton: false,
|
||||
timer: 1500
|
||||
})
|
||||
}
|
||||
|
||||
const handleBottomEnd = () => {
|
||||
return MySwal.fire({
|
||||
position: 'bottom-end',
|
||||
icon: 'success',
|
||||
title: 'Your work has been saved',
|
||||
showConfirmButton: false,
|
||||
timer: 1500
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Position</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<CardText className='mb-0'>
|
||||
You can specify position of your alert with
|
||||
<code>{'position : top-start | top-end | bottom-start | bottom-end '}</code>{' '}
|
||||
</CardText>
|
||||
<div className='demo-inline-spacing'>
|
||||
<Button color='primary' onClick={handleTopStart} outline>
|
||||
Top Start
|
||||
</Button>
|
||||
|
||||
<Button color='primary' onClick={handleTopEnd} outline>
|
||||
Top End
|
||||
</Button>
|
||||
|
||||
<Button color='primary' onClick={handleBottomStart} outline>
|
||||
Bottom Start
|
||||
</Button>
|
||||
|
||||
<Button color='primary' onClick={handleBottomEnd} outline>
|
||||
Bottom End
|
||||
</Button>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SweetAlertPositions
|
@ -1,85 +0,0 @@
|
||||
import { Card, CardHeader, CardBody, CardTitle, Button, CardText } from 'reactstrap'
|
||||
import Swal from 'sweetalert2'
|
||||
import withReactContent from 'sweetalert2-react-content'
|
||||
|
||||
const MySwal = withReactContent(Swal)
|
||||
|
||||
const SweetAlertTypes = () => {
|
||||
const handleSuccess = () => {
|
||||
return MySwal.fire({
|
||||
title: 'Good job!',
|
||||
text: 'You clicked the button!',
|
||||
icon: 'success',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
},
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
const handleInfo = () => {
|
||||
return MySwal.fire({
|
||||
title: 'Info!',
|
||||
text: 'You clicked the button!',
|
||||
icon: 'info',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
},
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
const handleWarning = () => {
|
||||
return MySwal.fire({
|
||||
title: 'Warning!',
|
||||
text: ' You clicked the button!',
|
||||
icon: 'warning',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
},
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
const handleError = () => {
|
||||
return MySwal.fire({
|
||||
title: 'Error!',
|
||||
text: ' You clicked the button!',
|
||||
icon: 'error',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
},
|
||||
buttonsStyling: false
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Types</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<CardText className='mb-0'>
|
||||
SweetAlert comes with 4 built-in types which will show a corresponding icon animation: "warning", "error",
|
||||
"success" and "info".
|
||||
</CardText>
|
||||
<div className='demo-inline-spacing'>
|
||||
<Button color='success' onClick={handleSuccess} outline>
|
||||
Success
|
||||
</Button>
|
||||
<Button color='danger' onClick={handleError} outline>
|
||||
Error
|
||||
</Button>
|
||||
<Button color='warning' onClick={handleWarning} outline>
|
||||
Warning
|
||||
</Button>
|
||||
<Button color='info' onClick={handleInfo} outline>
|
||||
Info
|
||||
</Button>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SweetAlertTypes
|
@ -1,46 +0,0 @@
|
||||
import { Fragment } from 'react'
|
||||
import ExtensionsHeader from '@components/extensions-header'
|
||||
import { Row, Col } from 'reactstrap'
|
||||
import SweetAlertBasic from './SweetAlertBasic'
|
||||
import SweetAlertPositions from './SweetAlertPositions'
|
||||
import SweetAlertAnimations from './SweetAlertAnimations'
|
||||
import SweetAlertTypes from './SweetAlertTypes'
|
||||
import SweetAlertOptions from './SweetAlertOptions'
|
||||
import SweetAlertCallback from './SweetAlertCallback'
|
||||
|
||||
import 'animate.css/animate.css'
|
||||
import '@styles/base/plugins/extensions/ext-component-sweet-alerts.scss'
|
||||
|
||||
const SweetAlert = () => {
|
||||
return (
|
||||
<Fragment>
|
||||
<ExtensionsHeader
|
||||
title='Sweet Alerts2'
|
||||
subTitle='A React implementation of SweetAlert2'
|
||||
link='https://github.com/sweetalert2/sweetalert2-react-content'
|
||||
/>
|
||||
<Row>
|
||||
<Col sm='12'>
|
||||
<SweetAlertBasic />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<SweetAlertPositions />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<SweetAlertAnimations />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<SweetAlertTypes />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<SweetAlertOptions />
|
||||
</Col>
|
||||
<Col sm='12'>
|
||||
<SweetAlertCallback />
|
||||
</Col>
|
||||
</Row>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default SweetAlert
|
@ -1,45 +0,0 @@
|
||||
import SwiperCore, { EffectCube, Pagination } from 'swiper'
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import img1 from '@src/assets/images/banner/banner-21.jpg'
|
||||
import img2 from '@src/assets/images/banner/banner-22.jpg'
|
||||
import img3 from '@src/assets/images/banner/banner-23.jpg'
|
||||
import img4 from '@src/assets/images/banner/banner-24.jpg'
|
||||
|
||||
const params = {
|
||||
effect: 'cube',
|
||||
className: 'swiper-cube-effect',
|
||||
pagination: {
|
||||
clickable: true
|
||||
}
|
||||
}
|
||||
|
||||
SwiperCore.use([EffectCube, Pagination])
|
||||
|
||||
const SwiperThreeD = ({ isRtl }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>3D Cube Effect</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper dir={isRtl ? 'rtl' : 'ltr'} {...params}>
|
||||
<SwiperSlide>
|
||||
<img src={img1} alt='swiper 1' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img2} alt='swiper 2' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img3} alt='swiper 3' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img4} alt='swiper 4' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperThreeD
|
@ -1,48 +0,0 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import { Play, DollarSign, HelpCircle, FileText, Archive } from 'react-feather'
|
||||
|
||||
const SwiperCenterSlidesStyle = ({ isRtl }) => {
|
||||
const params = {
|
||||
className: 'swiper-centered-slides p-1',
|
||||
slidesPerView: 'auto',
|
||||
spaceBetween: 30,
|
||||
centeredSlides: true,
|
||||
navigation: true,
|
||||
slideToClickedSlide: true
|
||||
}
|
||||
|
||||
return (
|
||||
<Card className='bg-transparent shadow-none'>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Centered Slides option-1</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper dir={isRtl ? 'rtl' : 'ltr'} {...params}>
|
||||
<SwiperSlide className='rounded swiper-shadow'>
|
||||
<Play size={28} />
|
||||
<p className='swiper-text align-middle pt-md-1 pt-sm-50 mb-0'>Getting Started</p>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide className='rounded swiper-shadow'>
|
||||
<DollarSign size={28} />
|
||||
<p className='swiper-text align-middle pt-md-1 pt-sm-50 mb-0'>Pricing & Plans</p>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide className='rounded swiper-shadow'>
|
||||
<HelpCircle size={28} />
|
||||
<p className='swiper-text align-middle pt-md-1 pt-sm-50 mb-0'>Sales Questions</p>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide className='rounded swiper-shadow'>
|
||||
<FileText size={28} />
|
||||
<p className='swiper-text align-middle pt-md-1 pt-sm-50 mb-0'>User Guides</p>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide className='rounded swiper-shadow'>
|
||||
<Archive size={28} />
|
||||
<p className='swiper-text align-middle pt-md-1 pt-sm-50 mb-0'>General Guides</p>
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperCenterSlidesStyle
|
@ -1,47 +0,0 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import { Play, DollarSign, HelpCircle, FileText, Archive } from 'react-feather'
|
||||
|
||||
const SwiperCenterSlidesStyle = ({ isRtl }) => {
|
||||
const params = {
|
||||
className: 'swiper-centered-slides-2 p-1',
|
||||
slidesPerView: 'auto',
|
||||
spaceBetween: 30,
|
||||
centeredSlides: true,
|
||||
slideToClickedSlide: true
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Centered Slides option-2</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper dir={isRtl ? 'rtl' : 'ltr'} {...params}>
|
||||
<SwiperSlide className='rounded swiper-shadow py-1 px-3 d-flex align-items-center'>
|
||||
<Play size={18} />
|
||||
<span className='swiper-text align-middle ml-50'>Getting Started</span>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide className='rounded swiper-shadow py-1 px-3 d-flex align-items-center'>
|
||||
<DollarSign size={18} />
|
||||
<span className='swiper-text align-middle ml-50'>Pricing & Plans</span>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide className='rounded swiper-shadow py-1 px-3 d-flex align-items-center'>
|
||||
<HelpCircle size={18} />
|
||||
<span className='swiper-text align-middle ml-50'>Sales Questions</span>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide className='rounded swiper-shadow py-1 px-3 d-flex align-items-center'>
|
||||
<FileText size={18} />
|
||||
<span className='swiper-text align-middle ml-50'>User Guides</span>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide className='rounded swiper-shadow py-1 px-3 d-flex align-items-center'>
|
||||
<Archive size={18} />
|
||||
<span className='swiper-text align-middle ml-50'>General Guides</span>
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperCenterSlidesStyle
|
@ -1,55 +0,0 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import img1 from '@src/assets/images/banner/banner-20.jpg'
|
||||
import img2 from '@src/assets/images/banner/banner-7.jpg'
|
||||
import img3 from '@src/assets/images/banner/banner-8.jpg'
|
||||
import img4 from '@src/assets/images/banner/banner-9.jpg'
|
||||
import img5 from '@src/assets/images/banner/banner-10.jpg'
|
||||
import img6 from '@src/assets/images/banner/banner-11.jpg'
|
||||
|
||||
const params = {
|
||||
spaceBetween: 30,
|
||||
centeredSlides: true,
|
||||
autoplay: {
|
||||
delay: 2500,
|
||||
disableOnInteraction: false
|
||||
},
|
||||
pagination: {
|
||||
clickable: true
|
||||
},
|
||||
navigation: true
|
||||
}
|
||||
|
||||
const SwiperAutoplay = ({ isRtl }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Autoplay</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper dir={isRtl ? 'rtl' : 'ltr'} {...params}>
|
||||
<SwiperSlide>
|
||||
<img src={img1} alt='swiper 1' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img2} alt='swiper 2' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img3} alt='swiper 3' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img4} alt='swiper 4' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img5} alt='swiper 5' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img6} alt='swiper 6' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperAutoplay
|
@ -1,71 +0,0 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import img1 from '@src/assets/images/banner/banner-35.jpg'
|
||||
import img2 from '@src/assets/images/banner/banner-39.jpg'
|
||||
import img3 from '@src/assets/images/banner/banner-38.jpg'
|
||||
import img4 from '@src/assets/images/banner/banner-37.jpg'
|
||||
import img5 from '@src/assets/images/banner/banner-36.jpg'
|
||||
import img6 from '@src/assets/images/banner/banner-34.jpg'
|
||||
import img7 from '@src/assets/images/banner/banner-33.jpg'
|
||||
import img8 from '@src/assets/images/banner/banner-32.jpg'
|
||||
import img9 from '@src/assets/images/banner/banner-31.jpg'
|
||||
|
||||
const params = {
|
||||
effect: 'coverflow',
|
||||
className: 'swiper-coverflow',
|
||||
slidesPerView: 'auto',
|
||||
centeredSlides: true,
|
||||
pagination: {
|
||||
clickable: true
|
||||
},
|
||||
coverflowEffect: {
|
||||
rotate: 50,
|
||||
stretch: 0,
|
||||
depth: 100,
|
||||
modifier: 1,
|
||||
slideShadows: true
|
||||
}
|
||||
}
|
||||
|
||||
const SwiperFade = ({ isRtl }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>3d Effect Coverflow Effect</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper dir={isRtl ? 'rtl' : 'ltr'} {...params}>
|
||||
<SwiperSlide>
|
||||
<img src={img1} alt='swiper 1' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img2} alt='swiper 2' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img3} alt='swiper 3' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img4} alt='swiper 4' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img5} alt='swiper 5' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img6} alt='swiper 6' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img7} alt='swiper 7' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img8} alt='swiper 8' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img9} alt='swiper 9' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperFade
|
@ -1,38 +0,0 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import img1 from '@src/assets/images/banner/banner-1.jpg'
|
||||
import img2 from '@src/assets/images/banner/banner-2.jpg'
|
||||
import img3 from '@src/assets/images/banner/banner-4.jpg'
|
||||
import img4 from '@src/assets/images/banner/banner-13.jpg'
|
||||
import img5 from '@src/assets/images/banner/banner-7.jpg'
|
||||
|
||||
const SwiperDefault = ({ isRtl }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Default</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper>
|
||||
<SwiperSlide dir={isRtl ? 'rtl' : 'ltr'}>
|
||||
<img src={img1} alt='swiper 1' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img2} alt='swiper 2' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img3} alt='swiper 3' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img4} alt='swiper 4' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img5} alt='swiper 5' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperDefault
|
@ -1,46 +0,0 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import img1 from '@src/assets/images/banner/banner-20.jpg'
|
||||
import img2 from '@src/assets/images/banner/banner-19.jpg'
|
||||
import img3 from '@src/assets/images/banner/banner-18.jpg'
|
||||
import img4 from '@src/assets/images/banner/banner-17.jpg'
|
||||
import img5 from '@src/assets/images/banner/banner-16.jpg'
|
||||
|
||||
const params = {
|
||||
effect: 'fade',
|
||||
navigation: true,
|
||||
pagination: {
|
||||
clickable: true
|
||||
}
|
||||
}
|
||||
|
||||
const SwiperFade = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Fade</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper {...params}>
|
||||
<SwiperSlide>
|
||||
<img src={img1} alt='swiper 1' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img2} alt='swiper 2' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img3} alt='swiper 3' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img4} alt='swiper 4' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img5} alt='swiper 5' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperFade
|
@ -1,83 +0,0 @@
|
||||
import { useState } from 'react'
|
||||
import SwiperCore, { Thumbs } from 'swiper'
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import img1 from '@src/assets/images/banner/banner-11.jpg'
|
||||
import img2 from '@src/assets/images/banner/banner-12.jpg'
|
||||
import img3 from '@src/assets/images/banner/banner-13.jpg'
|
||||
import img4 from '@src/assets/images/banner/banner-14.jpg'
|
||||
import img5 from '@src/assets/images/banner/banner-15.jpg'
|
||||
|
||||
SwiperCore.use([Thumbs])
|
||||
|
||||
const SwiperGallery = ({ isRtl }) => {
|
||||
const [thumbsSwiper, setThumbsSwiper] = useState(null)
|
||||
|
||||
const params = {
|
||||
className: 'swiper-gallery',
|
||||
spaceBetween: 10,
|
||||
navigation: true,
|
||||
pagination: {
|
||||
clickable: true
|
||||
},
|
||||
thumbs: { swiper: thumbsSwiper }
|
||||
}
|
||||
|
||||
const paramsThumbs = {
|
||||
className: 'gallery-thumbs',
|
||||
spaceBetween: 10,
|
||||
slidesPerView: 4,
|
||||
freeMode: true,
|
||||
watchSlidesVisibility: true,
|
||||
watchSlidesProgress: true,
|
||||
onSwiper: setThumbsSwiper
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Gallery</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<div className='swiper-gallery'>
|
||||
<Swiper dir={isRtl ? 'rtl' : 'ltr'} {...params}>
|
||||
<SwiperSlide>
|
||||
<img src={img1} alt='swiper 1' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img2} alt='swiper 2' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img3} alt='swiper 3' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img4} alt='swiper 4' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img5} alt='swiper 5' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
<Swiper {...paramsThumbs}>
|
||||
<SwiperSlide>
|
||||
<img src={img1} alt='swiper 1' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img2} alt='swiper 2' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img3} alt='swiper 3' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img4} alt='swiper 4' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img5} alt='swiper 5' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperGallery
|
@ -1,56 +0,0 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import img1 from '@src/assets/images/banner/banner-9.jpg'
|
||||
import img2 from '@src/assets/images/banner/banner-8.jpg'
|
||||
import img3 from '@src/assets/images/banner/banner-7.jpg'
|
||||
import img4 from '@src/assets/images/banner/banner-20.jpg'
|
||||
import img5 from '@src/assets/images/banner/banner-5.jpg'
|
||||
import img6 from '@src/assets/images/banner/banner-4.jpg'
|
||||
|
||||
const params = {
|
||||
lazy: true,
|
||||
navigation: true,
|
||||
pagination: {
|
||||
clickable: true
|
||||
}
|
||||
}
|
||||
|
||||
const SwiperLazyLoad = ({ isRtl }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Lazy Loading</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper dir={isRtl ? 'rtl' : 'ltr'} {...params}>
|
||||
<SwiperSlide>
|
||||
<img src={img1} alt='swiper 1' className='swiper-lazy img-fluid' />
|
||||
<div className='swiper-lazy-preloader swiper-lazy-preloader-white'></div>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img2} alt='swiper 2' className='swiper-lazy img-fluid' />
|
||||
<div className='swiper-lazy-preloader swiper-lazy-preloader-white'></div>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img3} alt='swiper 3' className='swiper-lazy img-fluid' />
|
||||
<div className='swiper-lazy-preloader swiper-lazy-preloader-white'></div>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img4} alt='swiper 4' className='swiper-lazy img-fluid' />
|
||||
<div className='swiper-lazy-preloader swiper-lazy-preloader-white'></div>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img5} alt='swiper 5' className='swiper-lazy img-fluid' />
|
||||
<div className='swiper-lazy-preloader swiper-lazy-preloader-white'></div>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img6} alt='swiper 6' className='swiper-lazy img-fluid' />
|
||||
<div className='swiper-lazy-preloader swiper-lazy-preloader-white'></div>
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperLazyLoad
|
@ -1,46 +0,0 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import img1 from '@src/assets/images/banner/banner-31.jpg'
|
||||
import img2 from '@src/assets/images/banner/banner-32.jpg'
|
||||
import img3 from '@src/assets/images/banner/banner-33.jpg'
|
||||
import img4 from '@src/assets/images/banner/banner-34.jpg'
|
||||
import img5 from '@src/assets/images/banner/banner-35.jpg'
|
||||
|
||||
const params = {
|
||||
slidesPerView: 3,
|
||||
spaceBetween: 30,
|
||||
pagination: {
|
||||
clickable: true
|
||||
}
|
||||
}
|
||||
|
||||
const SwiperMultiSlides = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Multi Slides Per View</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper {...params}>
|
||||
<SwiperSlide>
|
||||
<img src={img1} alt='swiper 1' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img2} alt='swiper 2' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img3} alt='swiper 3' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img4} alt='swiper 4' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img5} alt='swiper 5' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperMultiSlides
|
@ -1,42 +0,0 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import img1 from '@src/assets/images/banner/banner-7.jpg'
|
||||
import img2 from '@src/assets/images/banner/banner-4.jpg'
|
||||
import img3 from '@src/assets/images/banner/banner-14.jpg'
|
||||
import img4 from '@src/assets/images/banner/banner-3.jpg'
|
||||
import img5 from '@src/assets/images/banner/banner-2.jpg'
|
||||
|
||||
const params = {
|
||||
navigation: true
|
||||
}
|
||||
|
||||
const SwiperNavigation = ({ isRtl }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Navigation</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper dir={isRtl ? 'rtl' : 'ltr'} {...params}>
|
||||
<SwiperSlide>
|
||||
<img src={img1} alt='swiper 1' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img2} alt='swiper 2' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img3} alt='swiper 3' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img4} alt='swiper 4' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img5} alt='swiper 5' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperNavigation
|
@ -1,44 +0,0 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import img1 from '@src/assets/images/banner/banner-12.jpg'
|
||||
import img2 from '@src/assets/images/banner/banner-9.jpg'
|
||||
import img3 from '@src/assets/images/banner/banner-8.jpg'
|
||||
import img4 from '@src/assets/images/banner/banner-7.jpg'
|
||||
import img5 from '@src/assets/images/banner/banner-20.jpg'
|
||||
|
||||
const params = {
|
||||
pagination: {
|
||||
clickable: true
|
||||
}
|
||||
}
|
||||
|
||||
const SwiperPagination = ({ isRtl }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Pagination</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper dir={isRtl ? 'rtl' : 'ltr'} {...params}>
|
||||
<SwiperSlide>
|
||||
<img src={img1} alt='swiper 1' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img2} alt='swiper 2' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img3} alt='swiper 3' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img4} alt='swiper 4' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img5} alt='swiper 5' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperPagination
|
@ -1,45 +0,0 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import img1 from '@src/assets/images/banner/banner-8.jpg'
|
||||
import img2 from '@src/assets/images/banner/banner-7.jpg'
|
||||
import img3 from '@src/assets/images/banner/banner-20.jpg'
|
||||
import img4 from '@src/assets/images/banner/banner-5.jpg'
|
||||
import img5 from '@src/assets/images/banner/banner-4.jpg'
|
||||
|
||||
const params = {
|
||||
navigation: true,
|
||||
pagination: {
|
||||
type: 'progressbar'
|
||||
}
|
||||
}
|
||||
|
||||
const SwiperProgress = () => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Progress</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper {...params}>
|
||||
<SwiperSlide>
|
||||
<img src={img1} alt='swiper 1' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img2} alt='swiper 2' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img3} alt='swiper 3' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img4} alt='swiper 4' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img5} alt='swiper 5' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperProgress
|
@ -1,80 +0,0 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import img1 from '@src/assets/images/banner/banner-30.jpg'
|
||||
import img2 from '@src/assets/images/banner/banner-31.jpg'
|
||||
import img3 from '@src/assets/images/banner/banner-32.jpg'
|
||||
import img4 from '@src/assets/images/banner/banner-33.jpg'
|
||||
import img5 from '@src/assets/images/banner/banner-34.jpg'
|
||||
import img6 from '@src/assets/images/banner/banner-35.jpg'
|
||||
import img7 from '@src/assets/images/banner/banner-36.jpg'
|
||||
import img8 from '@src/assets/images/banner/banner-37.jpg'
|
||||
import img9 from '@src/assets/images/banner/banner-38.jpg'
|
||||
|
||||
const params = {
|
||||
slidesPerView: 5,
|
||||
spaceBetween: 50,
|
||||
pagination: {
|
||||
clickable: true
|
||||
},
|
||||
breakpoints: {
|
||||
1024: {
|
||||
slidesPerView: 4,
|
||||
spaceBetween: 40
|
||||
},
|
||||
768: {
|
||||
slidesPerView: 3,
|
||||
spaceBetween: 30
|
||||
},
|
||||
640: {
|
||||
slidesPerView: 2,
|
||||
spaceBetween: 20
|
||||
},
|
||||
320: {
|
||||
slidesPerView: 1,
|
||||
spaceBetween: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const SwiperResponsive = ({ isRtl }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Responsive</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper dir={isRtl ? 'rtl' : 'ltr'} {...params}>
|
||||
<SwiperSlide>
|
||||
<img src={img1} alt='swiper 1' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img2} alt='swiper 2' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img3} alt='swiper 3' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img4} alt='swiper 4' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img5} alt='swiper 5' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img6} alt='swiper 6' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img7} alt='swiper 7' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img8} alt='swiper 8' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img9} alt='swiper 9' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperResponsive
|
@ -1,68 +0,0 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
|
||||
import img1 from '@src/assets/images/banner/banner-26.jpg'
|
||||
import img2 from '@src/assets/images/banner/banner-39.jpg'
|
||||
import img3 from '@src/assets/images/banner/banner-28.jpg'
|
||||
import img4 from '@src/assets/images/banner/banner-29.jpg'
|
||||
import img5 from '@src/assets/images/banner/banner-30.jpg'
|
||||
import img6 from '@src/assets/images/banner/banner-31.jpg'
|
||||
import img7 from '@src/assets/images/banner/banner-32.jpg'
|
||||
import img8 from '@src/assets/images/banner/banner-33.jpg'
|
||||
import img9 from '@src/assets/images/banner/banner-34.jpg'
|
||||
import img10 from '@src/assets/images/banner/banner-35.jpg'
|
||||
|
||||
const params = {
|
||||
slidesPerView: 3,
|
||||
slidesPerColumn: 2,
|
||||
spaceBetween: 30,
|
||||
slidesPerColumnFill: 'row',
|
||||
pagination: {
|
||||
clickable: true
|
||||
}
|
||||
}
|
||||
|
||||
const SwiperMultiSlides = ({ isRtl }) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Multi Row Slides Layout</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper dir={isRtl ? 'rtl' : 'ltr'} {...params}>
|
||||
<SwiperSlide>
|
||||
<img src={img1} alt='swiper 1' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img2} alt='swiper 2' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img3} alt='swiper 3' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img4} alt='swiper 4' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img5} alt='swiper 5' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img6} alt='swiper 6' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img7} alt='swiper 7' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img8} alt='swiper 8' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img9} alt='swiper 9' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
<img src={img10} alt='swiper 10' className='img-fluid' />
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperMultiSlides
|
@ -1,58 +0,0 @@
|
||||
import { Card, CardHeader, CardTitle, CardBody, Button } from 'reactstrap'
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
|
||||
const SwiperVirtual = ({ isRtl }) => {
|
||||
const slides = []
|
||||
for (let i = 0; i < 10; i += 1) {
|
||||
slides.push(<SwiperSlide key={`slide-${i + 1}`}>Slide {i + 1}</SwiperSlide>)
|
||||
}
|
||||
|
||||
let instance = null
|
||||
|
||||
const appendSlide = () => {
|
||||
if (instance !== null) {
|
||||
slides.push(<SwiperSlide key={`slide-${slides.length + 1}`}>Slide {slides.length + 1}</SwiperSlide>)
|
||||
instance.update(true)
|
||||
}
|
||||
}
|
||||
|
||||
const removeSlide = () => {
|
||||
if (instance !== null) {
|
||||
instance.removeAllSlides()
|
||||
slides.length = 0
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle tag='h4'>Virtual</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Swiper
|
||||
dir={isRtl ? 'rtl' : 'ltr'}
|
||||
className='swiper-virtual'
|
||||
spaceBetween={50}
|
||||
slidesPerView={3}
|
||||
centeredSlides
|
||||
pagination={{ clickable: true }}
|
||||
onSwiper={swiper => (instance = swiper.virtual)}
|
||||
virtual
|
||||
>
|
||||
{slides}
|
||||
</Swiper>
|
||||
|
||||
<div className='demo-inline-spacing'>
|
||||
<Button color='primary' outline onClick={appendSlide}>
|
||||
Append Slide
|
||||
</Button>
|
||||
<Button className='mr-0' color='primary' outline onClick={removeSlide}>
|
||||
Remove All Slides
|
||||
</Button>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwiperVirtual
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user