Commit 30f0b4dd authored by Muhammadali's avatar Muhammadali

Initial commit

parents
Pipeline #224 canceled with stages
.DS_STORE
node_modules
scripts/flow/*/.flowconfig
.flowconfig
*~
*.pyc
.grunt
_SpecRunner.html
__benchmarks__
build/
remote-repo/
coverage/
.module-cache
fixtures/dom/public/react-dom.js
fixtures/dom/public/react.js
test/the-files-to-test.generated.js
*.log*
chrome-user-data
*.sublime-project
*.sublime-workspace
.idea
*.iml
.vscode
*.swp
*.swo
packages/react-devtools-core/dist
packages/react-devtools-extensions/chrome/build
packages/react-devtools-extensions/chrome/*.crx
packages/react-devtools-extensions/chrome/*.pem
packages/react-devtools-extensions/firefox/build
packages/react-devtools-extensions/firefox/*.xpi
packages/react-devtools-extensions/firefox/*.pem
packages/react-devtools-extensions/shared/build
packages/react-devtools-extensions/.tempUserDataDir
packages/react-devtools-inline/dist
packages/react-devtools-shell/dist
packages/react-devtools-timeline/dist
\ No newline at end of file
<!-- @format -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>React App</title>
<script defer src="main.js"></script></head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="app"></div>
</body>
</html>
This diff is collapsed.
This diff is collapsed.
{
"name": "boxdialer",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack serve --mode=development",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@headlessui/react": "^1.7.17",
"@heroicons/react": "^2.0.18",
"@mui/icons-material": "^5.14.3",
"@mui/material": "^5.14.5",
"date-fns": "^2.30.0",
"ecmascript-webrtc-sipml": "git+https://git.4u.uz/kulya/ecmascript-webrtc-sipml.git",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hot-toast": "^2.4.1",
"styled-components": "^6.0.7"
},
"devDependencies": {
"@babel/core": "^7.22.10",
"@babel/preset-env": "^7.22.10",
"@babel/preset-react": "^7.22.5",
"autoprefixer": "^9.8.8",
"babel-loader": "^9.1.3",
"css-loader": "^6.8.1",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.3",
"postcss": "^7.0.39",
"postcss-loader": "^7.3.3",
"style-loader": "^3.3.3",
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
}
}
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
/** @format */
import WidjetButton from './components/WidjetButton';
import { BoxDialer } from './lib/boxDIaler';
window.BoxDialer = new BoxDialer();
export default WidjetButton;
/** @format */
import React, { useEffect, useState } from 'react';
import MainBlock, { ModalContainer } from './style';
import VerticalAlignTopIcon from '@mui/icons-material/VerticalAlignTop';
const Modal = ({
children,
hidden,
hangupButton,
phoneNumber,
callType,
callAnswerType,
}) => {
const [rollUp, setRollUp] = useState(false);
const [modalHidden, setModalHidden] = useState(false);
useEffect(() => {
setModalHidden(hidden);
}, [hidden]);
if (!modalHidden) return;
const boxDialer = window.BoxDialer;
return (
<MainBlock hidden={modalHidden || modalHidden} rollUp={rollUp}>
<ModalContainer onClick={(e) => e.stopPropagation()} rollUp={rollUp}>
{children}
<ModalContainer.Top className={'top'} rollUp={rollUp}>
{callType === 'outcoming' ? (
<p>Звонок на {phoneNumber}</p>
) : (
<p>Звонок от {phoneNumber}</p>
)}
<p className='rollUpButton' onClick={() => setRollUp(true)}>
Свернуть
</p>
</ModalContainer.Top>
<hr />
<ModalContainer.Head rollUp={rollUp}>
<div className='round'></div>
<p className='name'>No name</p>
</ModalContainer.Head>
<hr />
<ModalContainer.Body rollUp={rollUp}></ModalContainer.Body>
<hr />
<ModalContainer.Bottom rollUp={rollUp}></ModalContainer.Bottom>
<hr />
{callType === 'outcoming' ? (
<ModalContainer.Footer rollUp={rollUp} onClick={() => hangupButton()}>
<button className='redButton'>ЗАКРЫТЬ</button>
</ModalContainer.Footer>
) : (
<ModalContainer.Footer rollUp={rollUp}>
<button
className='redButton'
onClick={() => boxDialer.skipButtonClick()}>
ЗАКРЫТЬ
</button>
{callAnswerType !== 'answered' && (
<button
className='greenButton'
onClick={() => boxDialer.answerButtonClick()}>
ОТВЕТИТЬ
</button>
)}
</ModalContainer.Footer>
)}
</ModalContainer>
<div className='rollUpVesion'>
<button
className='close'
onClick={() => {
hangupButton();
setRollUp(false);
setModalHidden(false);
}}>
ЗАКРЫТЬ
</button>
<button className='rollUpUn' onClick={() => setRollUp(false)}>
<VerticalAlignTopIcon />
</button>
</div>
</MainBlock>
);
};
export default Modal;
/** @format */
import styled from 'styled-components';
const MainBlock = styled.div`
z-index: 999999999999;
display: ${({ hidden }) => (hidden ? 'flex' : 'none')};
transition: 0.3s;
${({ rollUp }) =>
rollUp
? {
position: 'fixed',
transition: '0.3s',
width: '175px',
height: '45px',
bottom: '170px',
left: '50px',
borderRadius: '50px',
display: 'flex',
backgroundColor: '#37404bad',
alignItems: 'center',
padding: '10px',
}
: {
transition: '0.3s',
width: '100%',
height: '100%',
position: 'fixed',
bottom: '0',
left: '0',
backgroundColor: '#00000061',
justifyContent: 'center',
alignItems: 'center',
}}
.rollUpVesion {
display: ${({ rollUp }) => (!rollUp ? 'none' : 'flex')};
justify-content: space-between;
width: 100%;
}
.close {
background-color: #9d0f23;
border-radius: 50px;
padding: 7px 17px;
font-size: 12px;
color: #fff;
font-weight: bold;
}
.rollUpUn {
color: #d0d0d1;
}
`;
const ModalContainer = styled.div`
display: ${({ rollUp }) => (rollUp ? 'none' : 'block')};
background-color: #29303a;
border-radius: 3px;
width: 550px;
hr {
display: ${({ rollUp }) => (rollUp ? 'none' : 'block')};
height: 1px;
border-top: 1px solid #4c515a;
width: 93%;
margin: auto;
}
`;
ModalContainer.Top = styled.div`
display: ${({ rollUp }) => (rollUp ? 'none' : 'flex')};
padding: 15px;
align-items: center;
justify-content: space-between;
color: #bdc0c3;
.rollUpButton {
cursor: pointer;
}
`;
ModalContainer.Head = styled.div`
display: ${({ rollUp }) => (rollUp ? 'none' : 'flex')};
padding: 15px;
gap: 10px;
.round {
width: 54px;
height: 54px;
border-radius: 250px;
background-color: #ccc;
}
.name {
color: #fff;
font-size: 18px;
}
`;
ModalContainer.Body = styled.div`
display: ${({ rollUp }) => (rollUp ? 'none' : 'block')};
padding: 15px;
margin: 15px;
background-color: #232932;
padding: 10px 12px;
.title {
}
.description {
}
`;
ModalContainer.Bottom = styled.div`
margin: 15px;
display: ${({ rollUp }) => (rollUp ? 'none' : 'block')};
`;
ModalContainer.Footer = styled.div`
justify-content: center;
align-items: center;
padding: 15px;
gap: 20px;
.redButton {
background-color: #9d0f23;
border-radius: 50px;
padding: 10px 24px;
font-size: 12;
color: #fff;
font-weight: bold;
}
.greenButton {
background-color: green;
border-radius: 50px;
padding: 10px 24px;
font-size: 12;
color: #000;
font-weight: bold;
}
display: ${({ rollUp }) => (rollUp ? 'none' : 'flex')};
`;
export { ModalContainer };
export default MainBlock;
/** @format */
import React, { createElement } from 'react';
import * as MuiIcons from '@mui/icons-material';
export const MuiIcon = ({ iconName }) => {
try {
return <>{createElement(MuiIcons[iconName])}</>;
} catch {
return <>{createElement(MuiIcons['BubbleChart'])}</>;
}
};
export default MuiIcon;
export { MuiIcon as default } from './MuiIcon'
export * from './MuiIcon'
\ No newline at end of file
/** @format */
import { Menu, Transition } from '@headlessui/react';
import React, { Fragment } from 'react';
function classNames(...classes) {
return classes.filter(Boolean).join(' ');
}
const DropDownTailwind = ({ reasons, reason, selectFunc }) => {
return (
<Menu as='div' className='text-left w-full h-full'>
<div className='w-full'>
<Menu.Button
style={{
backgroundColor: '#5e5e5e',
width: '100%',
height: '30px',
color: 'white',
display: 'flex',
alignItems: 'center',
}}
className='inline-flex justify-center rounded-md font-semibold text-gray-900 shadow-sm hover:bg-gray-50 gap-1 border-0 text-sm'>
{reason ? reason : 'Nothing'}
</Menu.Button>
</div>
{reasons && reasons.length && (
<Transition
as={Fragment}
enter='transition ease-out duration-100'
enterFrom='transform opacity-0 scale-95'
enterTo='transform opacity-100 scale-100'
leave='transition ease-in duration-75'
leaveFrom='transform opacity-100 scale-100'
leaveTo='transform opacity-0 scale-95'>
<Menu.Items className='absolute left-1 z-10 mt-2 w-56 origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none'>
<div className='py-3 flex flex-col'>
{reasons.map((value) => (
<Menu.Item onClick={() => selectFunc(value)}>
{({ active }) => (
<p
className={classNames(
active ? 'bg-gray-100 text-gray-900' : 'text-gray-700',
'block px-5 py-1 text-lg',
)}>
{value}
</p>
)}
</Menu.Item>
))}
</div>
</Menu.Items>
</Transition>
)}
</Menu>
);
};
export default DropDownTailwind;
/** @format */
import React, { useEffect, useState } from 'react';
import { intervalToDuration } from 'date-fns';
const TimerUi = ({ reason, time }) => {
console.log(reason, time, 'dsahfhfghgf');
const boxDialer = window.BoxDialer;
const [dndTimer, setDndTimer] = useState(time);
useEffect(() => {
if (reason !== 'free') {
var intervalId = setInterval(() => {
console.log('ticking');
setDndTimer((prevCount) => prevCount + 1);
}, 1000);
return () => clearInterval(intervalId);
}
}, [reason]);
useEffect(() => {
setDndTimer(time);
}, [reason]);
const dataFormatter = (secund) => {
let ts = intervalToDuration({
start: 0,
end: secund * 1000,
});
return secund > 3599
? `${ts.hours}:${ts.minutes}:${ts.seconds}`
: `${ts.minutes}:${ts.seconds}`;
};
if (reason === 'free') {
return <></>;
}
return (
<span>
{boxDialer?.timer.type !== 'free' && (
<span>{dataFormatter(dndTimer)}</span>
)}
</span>
);
};
export default TimerUi;
/** @format */
import React, { useCallback, useEffect, useState } from 'react';
import WidjetBlock, {
DialPadIcon,
Input,
ModalPhoneDropDowm,
NumberButton,
} from './style';
import numbers from './numbers';
import Modal from '../Modal';
import CallIcon from '@mui/icons-material/Call';
import { toast } from 'react-hot-toast';
import DropDownTailwind from '../TailwindComponents/DropDown';
import TimerUi from '../TimerUi';
const WidjetButton = ({ data, onSetDnd }) => {
data = {
iscloud: true,
number: '4003',
wsurl: 'cld.alovoice.uz:61040',
server_id: 40,
secret: '26a830',
reason: 'free',
lefttime: 231461,
reasons: ['free', 'outcalls', 'home', 'totop'],
};
if (window?.alovoice_wsphone) {
data = window.alovoice_wsphone;
onSetDnd = window.alovoice_onsetdnd;
}
const [phoneModal, setPhoneModal] = useState(false);
const [inputValue, setInputValue] = useState('');
const [dynamicValue, setDynamicValue] = useState('pending');
const [modalState, setModalState] = useState(false);
const boxDialer = window.BoxDialer;
useEffect(() => {
if (data && data?.number) {
boxDialer.setSipStateChangeCallback(setDynamicValue, 'dynamicValue');
boxDialer.setSipStateChangeCallback(setModalState, 'modalState');
boxDialer.sipRegister(data);
}
}, []);
console.log(data, 'data');
useEffect(() => {
if (!modalState.bool) setInputValue('');
}, [modalState.bool]);
const inputController = ({ value, type, from }) => {
boxDialer.onSoundType({ type: 'pick', bool: true });
if (modalState.callType === 'outcoming' && modalState.bool) {
boxDialer.sipSendDTMF(value);
}
switch (type) {
case 'add':
if (
value.match(/^[a-zA-Z0-9!@#\$%\^\&*\)\(+=._-]+$/g).join('').length
) {
if (from === 'input') return setInputValue(value);
if (from === 'button') setInputValue(inputValue + value);
}
break;
case 'delete':
if (from === 'button') {
setInputValue(
inputValue
.split('')
.slice(0, inputValue.length - 1)
.join(''),
);
}
if (from === 'input') {
setInputValue(value);
}
break;
default:
break;
}
};
document.onkeydown = function (e) {
if (phoneModal) {
e = e || window.event;
if (e.ctrlKey && e.keyCode === 86) {
navigator.clipboard
.readText()
.then((text) => {
inputController({ type: 'add', value: text, from: 'button' });
})
.catch((err) => {
console.log('Something went wrong', err);
});
}
return true;
}
};
const gameState = {
toggleCP: (e) => {
if (phoneModal && e.key === 'Enter') {
boxDialer.initialized(inputValue, data.number);
} else if (phoneModal && e.key === 'Backspace') {
inputController({ type: 'delete', from: 'button', value: e.value });
} else if (phoneModal && !isNaN(+e.key)) {
inputController({ type: 'add', value: e.key, from: 'button' });
}
},
};
const handleKeyUp = useCallback(
(event) => {
console.log(event);
gameState.toggleCP(event);
},
[gameState.toggleCP],
);
useEffect(() => {
document.addEventListener('keyup', handleKeyUp);
return () => {
document.removeEventListener('keyup', handleKeyUp);
};
}, [handleKeyUp]);
const hangupButton = () => {
boxDialer.stopCall();
};
const callButton = () => {
if (dynamicValue === 'connected') {
boxDialer.initialized(inputValue, data.number);
} else {
toast.error('Please wait', {
style: {
zIndex: '99999999999999999',
},
});
}
};
if (!data || !data?.number) return;
return (
<>
<WidjetBlock
onClick={(e) => {
phoneModal ? setPhoneModal(false) : setPhoneModal(true);
}}>
<WidjetBlock.AccauntInfo status={dynamicValue}>
<div className='left'>
<p className='title'>{data?.number}</p>
<p>
<span className='status'>{dynamicValue}</span>
<TimerUi reason={data?.reason} time={data.lefttime} />
</p>
</div>
<div className='right'>
<DialPadIcon />
</div>
<div className='bottom'>
<WidjetBlock.StatusLine status={dynamicValue} />
</div>
</WidjetBlock.AccauntInfo>
<ModalPhoneDropDowm
hidden={!phoneModal}
onClick={(e) => e.stopPropagation()}>
<ModalPhoneDropDowm.InputArea>
<Input disabled type='text' value={inputValue} />
{inputValue.length ? (
<Input.BackSpaceIcon
onClick={() =>
inputController({ type: 'delete', from: 'button' })
}
/>
) : (
''
)}
</ModalPhoneDropDowm.InputArea>
<ModalPhoneDropDowm.ButtonArea>
{numbers?.map((mapItem) => (
<NumberButton
key={mapItem.id}
onClick={() => {
mapItem.type === 'number' &&
inputController({
value: mapItem.value,
type: 'add',
from: 'button',
});
}}>
{mapItem.nameNumber}
<NumberButton.Icon>{mapItem.icon}</NumberButton.Icon>
</NumberButton>
))}
{!modalState.bool ? (
<>
<NumberButton style={{ gridColumn: '1/3' }}>
<DropDownTailwind
selectFunc={onSetDnd}
reasons={data.reasons}
reason={data.reason}
/>
</NumberButton>
<NumberButton
onClick={() => callButton()}
// onClick={() => boxDialer.stopTimer()}
status={dynamicValue}
type={'call_button'}>
<CallIcon />
</NumberButton>
</>
) : (
<>
<div style={{ height: '33px' }}></div>
<div style={{ height: '33px' }}></div>
</>
)}
</ModalPhoneDropDowm.ButtonArea>
</ModalPhoneDropDowm>
</WidjetBlock>
<Modal
callAnswerType={modalState.callType}
hidden={modalState.bool}
callType={modalState.callType}
hangupButton={hangupButton}
phoneNumber={
modalState.callType === 'outcoming'
? inputValue
: modalState.callFromName
}
/>
</>
);
};
export default WidjetButton;
/** @format */
const numbers = [
{
id: 8,
nameNumber: '7',
value: '7',
type: 'number',
style: {},
icon: null,
},
{
id: 9,
nameNumber: '8',
value: '8',
type: 'number',
style: {},
icon: null,
},
{
id: 14,
nameNumber: '9',
value: '9',
type: 'number',
style: {},
icon: null,
},
{
id: 5,
nameNumber: '4',
value: '4',
type: 'number',
style: {},
icon: null,
},
{
id: 6,
nameNumber: '5',
value: '5',
type: 'number',
style: {},
icon: null,
},
{
id: 7,
nameNumber: '6',
value: '6',
type: 'number',
style: {},
icon: null,
},
{
id: 2,
nameNumber: '1',
value: '1',
type: 'number',
style: {},
icon: null,
},
{
id: 3,
nameNumber: '2',
value: '2',
type: 'number',
style: {},
icon: null,
},
{
id: 4,
nameNumber: '3',
value: '3',
type: 'number',
style: {},
icon: null,
},
{
id: 10,
nameNumber: '*',
value: '*',
type: 'number',
style: {},
icon: null,
},
{
id: 1,
nameNumber: '0',
value: '0',
type: 'number',
style: {},
icon: null,
},
{
id: 11,
nameNumber: '#',
value: '#',
type: 'number',
style: {},
icon: null,
},
// {
// id: 12,
// nameNumber: (
// <>
// <DropDown />
// </>
// ),
// type: 'DND_BUTTON',
// value: '#',
// style: { gridColumn: '1/3' },
// icon: null,
// },
// {
// id: 13,
// nameNumber: '',
// type: 'CALL_BUTTON',
// value: '#',
// style: { backgroundColor: '#bbed21', color: '#535c69' },
// icon: (
// <div
// style={{
// display: 'flex',
// alignItems: 'center',
// justifyContent: 'center',
// }}>
// <CallIcon />
// </div>
// ),
// },
];
export default numbers;
/** @format */
import styled from 'styled-components';
import CallIcon from '@mui/icons-material/Dialpad';
import KeyboardBackspaceIcon from '@mui/icons-material/KeyboardBackspace';
const WidjetBlock = styled.div`
position: fixed;
bottom: 30px;
left: 50px;
border-radius: 13px;
background-color: #164e63e6;
cursor: pointer;
color: white;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
height: 70px;
min-width: 180px;
max-width: 200px;
z-index: 9999999999999999999;
`;
WidjetBlock.AccauntInfo = styled.div`
height: 100%;
display: grid;
grid-template-columns: 1fr 30px;
grid-template-rows: 1fr 10px;
align-items: center;
.left {
display: flex;
flex-direction: column;
align-items: center;
}
.right {
}
.title {
font-size: 22px;
font-weight: 600;
}
.bottom {
height: 100%;
grid-column: 1/3;
grid-row: 2/3;
}
.status {
border-radius: 10px;
padding: 0 5px;
margin: 0 5px;
background-color: ${({ status }) =>
status === 'pending'
? 'orange'
: status === 'connected'
? '#a0c13d'
: '#ccc'};
color: ${({ status }) =>
status === 'pending' ? '#fff' : status === 'connected' ? '#333' : '#ccc'};
}
`;
WidjetBlock.StatusLine = styled.div`
height: 100%;
background-color: ${({ backColor }) => backColor};
border-bottom-left-radius: 30px;
border-bottom-right-radius: 30px;
background-color: ${({ status }) =>
status === 'pending'
? 'orange'
: status === 'connected'
? '#a0c13d'
: '#ccc'};
`;
const DialPadIcon = styled(CallIcon)`
font-size: 26px;
`;
const ModalPhoneDropDowm = styled.div`
width: 230px;
position: absolute;
bottom: 135px;
transition: 0.2s;
z-index: 99999999999999;
transform: translate(${({ hidden }) => (hidden ? '-200%' : '-50%')}, 0%);
left: 50%;
background-color: #c9d5d9;
border-radius: 20px;
padding: 15px;
display: grid;
grid-template-rows: 40px 1fr;
grid-gap: 15px;
cursor: default;
`;
ModalPhoneDropDowm.InputArea = styled.div`
position: relative;
`;
ModalPhoneDropDowm.ButtonArea = styled.div`
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 8px;
`;
const NumberButton = styled.div`
background-color: #5e5e5e;
color: #fff;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
border-radius: 7px;
font-size: 22px;
cursor: pointer;
height: 33px;
background-color: ${({ status, type }) =>
type === 'call_button' && status === 'pending'
? 'orange'
: status === 'connected' && '#a0c13d'};
`;
NumberButton.Icon = styled.div`
font-size: 20px;
`;
const Input = styled.input`
position: absolute;
width: 100%;
height: 100%;
border-radius: 3px;
background-color: #fff;
border: 0 !important;
padding: 0px 35px 0 10px;
font-size: 22px;
color: #000;
:focus {
border-color: inherit;
-webkit-box-shadow: none;
box-shadow: none;
padding: 0 10px;
font-size: 24px;
outline: 0 none;
}
position: relative;
display: inline-block;
margin: 0;
outline: none;
border: 0;
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
&[type='number'] {
-moz-appearance: textfield;
}
`;
Input.BackSpaceIcon = styled(KeyboardBackspaceIcon)`
color: black;
position: absolute;
top: 5px;
right: 5px;
cursor: pointer;
top: 50%;
transform: translate(0, -50%);
`;
const Select = styled.select`
width: 100%;
height: 100%;
:focus {
border-color: inherit;
-webkit-box-shadow: none;
box-shadow: none;
padding: 0 10px;
font-size: 24px;
outline: 0 none;
}
position: relative;
display: inline-block;
margin: 0;
outline: none;
border: 0;
background-color: #5e5e5e;
color: #fff;
font-size: 18px;
border-radius: 7px;
padding: 5px;
`;
export { DialPadIcon, ModalPhoneDropDowm, NumberButton, Input, Select };
export default WidjetBlock;
@tailwind base;
@tailwind components;
@tailwind utilities;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
\ No newline at end of file
<!-- @format -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="app"></div>
</body>
</html>
/** @format */
import React from 'react';
import ReactDOM from 'react-dom';
import { Toaster } from 'react-hot-toast';
import WidjetButton from './components/WidjetButton/index';
import { BoxDialer } from './lib/boxDIaler';
import './index.css';
window.BoxDialer = new BoxDialer();
ReactDOM.render(
<React.StrictMode>
<Toaster />
<WidjetButton />
</React.StrictMode>,
document.getElementById('app'),
);
This diff is collapsed.
/**
* @format
* @type {import('tailwindcss').Config}
*/
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}',
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
// Or if using `src` directory:
'./src/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {},
},
plugins: [],
};
/** @format */
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.join(__dirname, 'src', 'index.js'),
mode: 'development',
output: {
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.(jsx|js)$/,
use: {
loader: 'babel-loader',
options: {
presets: [['@babel/env', { loose: true }], '@babel/preset-react'],
},
},
},
{
test: /\.css$/i,
use: ['style-loader', 'css-loader', 'postcss-loader'],
},
{
test: /\.(png|jp(e*)g|svg|gif)$/,
use: ['file-loader'],
},
{
test: /\.svg$/,
use: ['@svgr/webpack'],
},
{
test: /\.(mp3|wav)$/i,
loader: 'file-loader',
},
],
},
resolve: {
extensions: ['.js', '.jsx', '.json'],
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src', 'index.html'),
}),
],
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment