Slicing UI

This commit is contained in:
2024-11-25 17:51:46 +07:00
parent 231c637fa9
commit 392a8a08fb
54 changed files with 8055 additions and 76 deletions

View File

@@ -0,0 +1,212 @@
import React, { useState, useEffect } from 'react';
import { useLocation } from 'react-router-dom';
const CreateSettings = () => {
const location = useLocation();
const [isMobile, setIsMobile] = useState(window.innerWidth <= 768);
useEffect(() => {
const handleResize = () => setIsMobile(window.innerWidth <= 768);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
const Breadcrumb = ({ path }) => {
return (
<nav style={styles.breadcrumb}>
{path.map((item, index) => (
<span key={index}>
{index > 0 && ' > '}
<a
href={item.link}
style={{
...styles.breadcrumbLink,
fontWeight: location.pathname === item.link ? 'bold' : 'normal',
}}
>
{item.name}
</a>
</span>
))}
</nav>
);
};
const breadcrumbPath = [
{ name: 'Wa Integration', link: '/wa-integration' },
{ name: 'Add Setting', link: '/wa-createSettings' },
];
return (
<div style={styles.container}>
<div style={isMobile ? styles.wrapperMobile : styles.wrapper}>
<Breadcrumb path={breadcrumbPath} />
<h2 style={styles.header}>Create Settings</h2>
<div style={isMobile ? styles.formWrapperMobile : styles.formWrapper}>
{/* Left Form Section */}
<div style={styles.formSection}>
<div style={styles.inputGroup}>
<label style={styles.label}>Application ID</label>
<select style={styles.input}>
<option value="">Select Application</option>
</select>
</div>
<div style={styles.inputGroup}>
<label style={styles.label}>Inbound Configuration</label>
<select style={styles.input}>
<option value="">Select Configuration</option>
</select>
</div>
<div style={styles.inputGroup}>
<label style={styles.label}>Webhook URL</label>
<input
type="text"
placeholder="Enter Webhook URL"
style={styles.input}
/>
</div>
<div style={styles.inputGroup}>
<label style={styles.label}>Event</label>
<div style={styles.checkboxGroup}>
<label>
<input type="checkbox" />
Message Created
</label>
<label>
<input type="checkbox" />
Message Updated
</label>
</div>
</div>
<button style={styles.button}>Add Now</button>
</div>
{/* Right WhatsApp Details Section */}
<div style={styles.detailSection}>
<h3 style={styles.detailHeader}>WhatsApp Channel Detail</h3>
<div style={styles.detailItem}>
<strong>Business Account Name:</strong> RekanVeri
</div>
<div style={styles.detailItem}>
<strong>WABA ID:</strong> 112917284928438
</div>
<div style={styles.detailItem}>
<strong>WhatsApp Number:</strong> 6287736766208
</div>
<div style={styles.detailItem}>
<strong>Channel Name:</strong> RekanVeri
</div>
<div style={styles.detailItem}>
<strong>Eligible for Inbound:</strong> YES
</div>
</div>
</div>
</div>
</div>
);
};
export default CreateSettings;
const styles = {
container: {
padding: '1rem',
width: '100%',
margin: '0 auto',
boxSizing: 'border-box',
},
wrapper: {
display: 'flex',
flexDirection: 'column',
border: '1px solid #ddd',
borderRadius: '8px',
padding: '1.5rem',
boxShadow: '0 2px 5px rgba(0, 0, 0, 0.1)',
backgroundColor: '#fff',
maxWidth: '1200px',
margin: '0 auto',
},
wrapperMobile: {
display: 'flex',
flexDirection: 'column',
border: '1px solid #ddd',
borderRadius: '8px',
padding: '1rem',
boxShadow: '0 2px 5px rgba(0, 0, 0, 0.1)',
backgroundColor: '#fff',
},
breadcrumb: {
marginBottom: '1rem',
fontSize: '0.9rem',
},
breadcrumbLink: {
textDecoration: 'none',
color: '#0542cc',
},
header: {
marginBottom: '1rem',
fontSize: '1.5rem',
},
formWrapper: {
display: 'flex',
gap: '2rem',
marginTop: '1rem',
},
formWrapperMobile: {
display: 'flex',
flexDirection: 'column',
gap: '1rem',
marginTop: '1rem',
},
formSection: {
flex: 2,
display: 'flex',
flexDirection: 'column',
gap: '1rem',
},
inputGroup: {
display: 'flex',
flexDirection: 'column',
gap: '0.5rem',
},
label: {
fontWeight: 'bold',
},
input: {
padding: '0.5rem',
border: '1px solid #ddd',
borderRadius: '4px',
width: '100%',
},
checkboxGroup: {
display: 'flex',
flexDirection: 'column',
gap: '0.5rem',
},
button: {
padding: '0.8rem 1.5rem',
backgroundColor: '#0542cc',
color: '#fff',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
alignSelf: 'flex-start',
},
detailSection: {
flex: 1,
backgroundColor: '#f5f9ff',
padding: '1rem',
border: '1px solid #ddd',
borderRadius: '8px',
},
detailHeader: {
fontSize: '1.2rem',
marginBottom: '1rem',
color: '#0542cc',
},
detailItem: {
marginBottom: '0.5rem',
fontSize: '0.9rem',
},
};

View File

@@ -0,0 +1,256 @@
import React, { useState, useEffect } from 'react';
import { WAB_1, WAB_2 } from '../../../../assets/images';
import { RegisterStep } from '../Content';
// Header component
const HeaderComponent = ({ isMobile }) => {
return (
<div style={isMobile ? styles.headerContainerMobile : styles.headerContainer}>
<img src={WAB_1} alt="WAB_1" style={styles.image(isMobile ? 200 : 350, isMobile ? 100 : 170)} />
<div style={styles.textContainer}>
<h2 style={styles.textTitle}>API For Your WhatsApp Business</h2>
<p style={styles.textBody}>
WhatsApp is one of the most popular communication platforms globally. As a Facebook-owned company,
setting up WhatsApp Business API requires a Facebook account and Facebook Business Manager.
Start leveraging this powerful tool for seamless communication with your customers.
</p>
</div>
</div>
);
};
// Step Component (untuk menampilkan 4 langkah yang ada)
const StepComponent = ({ isMigration, isMobile }) => {
const stepsData = isMigration
? [
{ number: '01', description: 'A Viable Phone Number for WhatsApp' },
{ number: '02', description: 'Your Business Legal address and details' },
]
: [
{ number: '01', description: 'A Viable Phone Number for WhatsApp' },
{ number: '02', description: 'Your Business Legal address and details' },
{ number: '03', description: 'Select Number you want to connect' },
{ number: '04', description: 'Verify your Facebook Business' },
];
return (
<div style={isMobile ? styles.stepsContainerMobile : styles.stepsContainer}>
{stepsData.map((step, index) => (
<div key={index} style={styles.step}>
<div style={styles.stepNumberContainer}>
<span style={styles.stepNumber}>{step.number}</span>
</div>
<p style={styles.stepDescription}>{step.description}</p>
</div>
))}
</div>
);
};
// Info Box Component untuk setiap informasi
const InfoComponent = ({ title, description, onStartNow, isMobile }) => {
return (
<div style={isMobile ? styles.infoBoxMobile : styles.infoBox}>
<h3>{title}</h3>
<p>{description}</p>
<button style={styles.startButton} onClick={onStartNow}>Start Now</button>
</div>
);
};
// Need Component (Menggabungkan Step dan Info Pertama)
const Need = ({ onStartNow, isMobile }) => {
return (
<div style={styles.regisBusinessContainer}>
<div style={styles.rowContainer}>
<div style={styles.col6}>
<StepComponent isMobile={isMobile} />
</div>
<div style={styles.col6}>
<InfoComponent
title="What You Need?"
description="To register for WhatsApp Business API, you'll need an active phone number,
your business's legal address and details, select the number you want to connect, and
verify your Facebook Business account to complete the setup."
onStartNow={onStartNow}
isMobile={isMobile}
/>
</div>
</div>
</div>
);
};
// Migration Component (Menggabungkan Step dan Info Kedua)
const Migration = ({ isMobile }) => {
return (
<div style={styles.regisBusinessContainer}>
<div style={styles.rowContainer}>
<div style={styles.col6}>
<div style={styles.leftSideContainer}>
<img src={WAB_2} alt="WAB_2" style={styles.image(isMobile ? 100 : 180, isMobile ? 100 : 180)} />
<StepComponent isMigration={true} isMobile={isMobile} />
</div>
</div>
<div style={styles.col6}>
<InfoComponent
title="What You Need for Migration?"
description="To complete the migration, you'll need a verified Facebook Business account
and access to the phone number you wish to migrate."
isMobile={isMobile}
/>
</div>
</div>
</div>
);
};
// Main component
const RegisterContent = () => {
const [isStarted, setIsStarted] = useState(false);
const [isMobile, setIsMobile] = useState(window.innerWidth <= 768);
// Update isMobile state on window resize
useEffect(() => {
const handleResize = () => setIsMobile(window.innerWidth <= 768);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
const handleStartNow = () => {
setIsStarted(true);
};
return (
<div style={styles.regisBusinessContainer}>
{!isStarted && <HeaderComponent isMobile={isMobile} />}
{!isStarted && <Need onStartNow={handleStartNow} isMobile={isMobile} />}
{!isStarted && <Migration isMobile={isMobile} />}
{isStarted && <RegisterStep />}
</div>
);
};
const styles = {
regisBusinessContainer: {
padding: '1rem',
margin: 'auto',
fontFamily: 'Arial, sans-serif'
},
// Header Content Style
headerContainer: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
marginBottom: '20px',
},
leftSideContainer: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: '10px',
},
image: (width, height) => ({
width: width,
height: height,
flex: '1 1 33%',
alignSelf: 'flex-start',
}),
textContainer: {
flex: '1 1 66%',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-end',
paddingLeft: '20px',
},
textTitle: {
fontSize: '24px',
fontWeight: 'bold',
marginBottom: '10px',
},
textBody: {
fontSize: '16px',
lineHeight: '1.5',
},
rowContainer: {
display: 'flex',
flexDirection: 'row',
marginTop: '20px',
flexWrap: 'wrap',
borderRadius: '8px',
border: '1px solid #ddd',
boxShadow: '0px 2px 8px rgba(0, 0, 0, 0.1)',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
minHeight: '200px',
},
col6: {
flex: '1 1 50%',
padding: '10px',
boxSizing: 'border-box',
},
// Step Style
stepsContainer: {
display: 'flex',
flexWrap: 'wrap',
gap: '10px', // Jarak antar langkah
position: 'relative', // Posisi relatif agar connectorLine bisa diposisikan dengan benar
},
step: {
flex: '1 1 16.6%', // Menyusun setiap langkah untuk mengambil 1/6 dari lebar container
padding: '10px',
boxSizing: 'border-box',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
textAlign: 'center',
marginBottom: '10px',
position: 'relative', // Agar connectorLine bisa diposisikan di dalam step
},
stepNumberContainer: {
width: '40px', // Menentukan lebar oval
height: '40px', // Menentukan tinggi oval
borderRadius: '50%', // Membuat bentuk oval
backgroundColor: '#0542CC', // Warna latar belakang oval
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginBottom: '8px',
},
stepNumber: {
fontSize: '16px',
color: '#fff', // Warna teks putih di dalam oval
fontWeight: 'bold',
},
stepDescription: {
fontSize: '14px',
lineHeight: '1.5',
color: '#333',
textAlign: 'center',
margin: '10px 0',
},
// Info Style
infoBox: {
padding: '20px',
marginBottom: '20px',
},
startButton: {
backgroundColor: '#0542cc',
color: '#fff',
padding: '10px 20px',
border: 'none',
borderRadius: '5px',
cursor: 'pointer',
marginTop: '15px',
},
};
export default RegisterContent;

View File

@@ -0,0 +1,455 @@
import React, { useState, useEffect } from 'react'
import { WAB_2 } from '../../../../assets/images';
const HeaderComponent = () => {
const isMobile = useIsMobile();
return (
<div style={{ ...styles.headerContainer, flexDirection: isMobile ? 'column' : 'row' }}>
<div style={styles.textContainer} className='p-3'>
<h2 style={styles.textTitle}>Registration Step</h2>
<p style={styles.textBody}>
WhatsApp is one of the most popular communication platforms globally. As a Facebook-owned company,
setting up WhatsApp Business API requires a Facebook account and Facebook Business Manager.
Start leveraging this powerful tool for seamless communication with your customers.
</p>
</div>
<img src={WAB_2} alt="WAB_2" style={styles.image(190, 190)} />
</div>
);
};
const useIsMobile = () => {
const [isMobile, setIsMobile] = useState(window.innerWidth <= 768);
useEffect(() => {
const handleResize = () => setIsMobile(window.innerWidth <= 768);
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return isMobile;
};
const InfoComponent = ({ title, description, onStartNow }) => {
const [isChecked, setIsChecked] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
const handleCheckboxChange = (event) => {
setIsChecked(event.target.checked);
setErrorMessage('');
};
const handleStartNow = () => {
if (!isChecked) {
setErrorMessage('Please confirm agreement on above!');
} else {
onStartNow();
}
};
return (
<div style={styles.contentContainer}>
<h3>{title}</h3>
<p>{description}</p>
<ul style={styles.descriptionList}>
<li>The number must be owned by your company.</li>
<li>Do not use a personal number.</li>
<li>It should not be actively registered on WhatsApp Messenger or WhatsApp Business App.</li>
<li>You must be able to receive phone calls or SMS on the number during the setup process.</li>
</ul>
<div style={styles.checkboxContainer}>
<input
type="checkbox"
id="agreement"
style={styles.checkbox}
checked={isChecked}
onChange={handleCheckboxChange}
/>
<label htmlFor="agreement" style={styles.checkboxLabel}>
I have a number with the above requirements
</label>
</div>
{errorMessage && (
<p style={{ color: 'red', fontSize: '0.875rem' }}>{errorMessage}</p>
)}
<button style={styles.startButton} onClick={handleStartNow}>
Start Now
</button>
</div>
);
};
// StepComponent
const StepComponent = ({ activeStep }) => {
const stepsData = [
{ number: '01', description: 'Phone Number to WhatsApp' },
{ number: '02', description: 'WhatsApp Business Channel' },
{ number: '03', description: 'Verify Your Business on Facebook' },
];
return (
<div style={styles.stepsContainer}>
{stepsData.map((step, index) => {
const isCurrent = activeStep === index;
return (
<div key={index} style={styles.step}>
<div
style={{
...styles.stepNumberContainer,
backgroundColor: isCurrent ? '#0542cc' : '#d3d3d3',
}}
>
<span
style={{
...styles.stepNumber,
color: isCurrent ? '#fff' : '#808080',
}}
>
{step.number}
</span>
</div>
<p
style={{
...styles.stepDescription,
color: isCurrent ? '#000' : 'gray',
}}
>
{step.description}
</p>
</div>
);
})}
</div>
);
};
// FirstContentComponent
const FirstContentComponent = ({ onStartNow }) => (
<div style={styles.rowContainer}>
<div style={styles.col6}>
<StepComponent activeStep={0} /> {/* Displays step 1 as active */}
</div>
<div style={styles.col6}>
<InfoComponent
title="Following Specifications Step"
onStartNow={onStartNow} // Handles "Start Now" button click
/>
</div>
</div>
);
// SecondContentComponent
const SecondContentComponent = ({ onNextStep, onBack }) => {
const [isChecked, setIsChecked] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
const handleCheckboxChange = (event) => {
setIsChecked(event.target.checked);
setErrorMessage(''); // Reset error message if checkbox is changed
};
const handleNextStep = () => {
if (!isChecked) {
setErrorMessage('Please confirm agreement on above!');
} else {
onNextStep(); // Proceed to next step if checkbox is checked
}
};
return (
<div style={styles.rowContainer}>
<div style={styles.col6}>
<StepComponent activeStep={1} /> {/* Displays step 2 as active */}
</div>
<div style={styles.col6}>
<p>You'll need the following information for your WhatsApp Business Channel, Be sure to have them on hand.</p>
<ul style={styles.descriptionList}>
<li>Your brand's Display Name, shown to customers you chat with.</li>
<li>Your company's Legal business name.</li>
<li>Your company's official address.</li>
</ul>
<p>Create your WhatsApp Business Channel</p>
<p>You'll be directed to Facebook Business Manager. Complete all the steps in the pop-up in order to create your WhatsApp Business Channel</p>
<div style={styles.checkboxContainer}>
<input
type="checkbox"
id="agreement"
style={styles.checkbox}
checked={isChecked}
onChange={handleCheckboxChange}
/>
<label htmlFor="agreement" style={styles.checkboxLabel}>
Create Your Own Channel
</label>
</div>
{errorMessage && (
<p style={{ color: 'red', fontSize: '0.875rem' }}>{errorMessage}</p>
)}
<button onClick={onBack} style={styles.backButton}>
Back
</button>
<button onClick={handleNextStep} style={styles.startButton}>
Next Step
</button>
</div>
</div>
);
};
// LastContentComponent (ThirdComponent)
const LastContentComponent = ({ onBack }) => {
const [isChecked, setIsChecked] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
const handleCheckboxChange = (event) => {
setIsChecked(event.target.checked);
setErrorMessage(''); // Reset error message if checkbox is changed
};
const handleFinish = () => {
if (!isChecked) {
setErrorMessage('Please confirm agreement on above!');
} else {
// Perform the final action here (e.g., submit form, complete registration)
alert('Registration Complete');
}
};
return (
<div style={styles.rowContainer}>
<div style={styles.col6}>
<StepComponent activeStep={2} /> {/* Displays step 3 as active */}
</div>
<div style={styles.col6}>
<p>Ensure your business is fully verified by completing the required steps on Facebook. This process is essential to activate and manage your WhatsApp Business API effectively.</p>
<div style={styles.checkboxContainer}>
<input
type="checkbox"
id="agreement"
style={styles.checkbox}
checked={isChecked}
onChange={handleCheckboxChange}
/>
<label htmlFor="agreement" style={styles.checkboxLabel}>
Verify Your Business on Facebook
</label>
</div>
{errorMessage && (
<p style={{ color: 'red', fontSize: '0.875rem' }}>{errorMessage}</p>
)}
<button onClick={onBack} style={styles.backButton}>
Back
</button>
<button onClick={handleFinish} style={styles.startButton}>
Finish
</button>
</div>
</div>
);
};
// Main Component
const RegisterStep = () => {
const [activeStep, setActiveStep] = useState(0);
const isMobile = useIsMobile();
const handleStartNow = () => {
setActiveStep(1); // Move to the second step
};
const handleNextStep = () => {
setActiveStep(activeStep + 1); // Move to the next step
};
const handleBack = () => {
setActiveStep(activeStep - 1); // Move to the previous step
};
const responsiveStyles = isMobile
? { flexDirection: 'column', alignItems: 'flex-start' }
: { flexDirection: 'row' };
return (
<div>
<HeaderComponent />
<div style={{ ...styles.rowContainer, ...responsiveStyles }}>
{activeStep === 0 && (
<FirstContentComponent onStartNow={handleStartNow} />
)}
{activeStep === 1 && (
<SecondContentComponent onNextStep={handleNextStep} onBack={handleBack} />
)}
{activeStep === 2 && (
<LastContentComponent onBack={handleBack} />
)}
</div>
</div>
);
};
export default RegisterStep
const styles = {
rowContainer: {
display: 'flex',
flexDirection: 'row',
marginTop: '20px',
flexWrap: 'wrap',
borderRadius: '8px',
border: '1px solid #ddd',
boxShadow: '0px 2px 8px rgba(0, 0, 0, 0.1)',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
minHeight: '200px',
},
col6: {
flex: '1 1 48%', // Membagi ruang menjadi 2 kolom
padding: '10px',
boxSizing: 'border-box',
},
headerContainer: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
marginBottom: '20px',
borderRadius: '8px',
border: '1px solid #ddd',
boxShadow: '0px 2px 8px rgba(0, 0, 0, 0.1)',
justifyContent: 'center',
width: '100%',
minHeight: '250px',
},
leftSideContainer: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: '10px',
},
image: (width, height) => ({
width: width,
height: height,
flex: '1 1 33%',
}),
textContainer: {
flex: '1 1 66%',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-end',
paddingLeft: '20px',
},
textTitle: {
fontSize: '24px',
fontWeight: 'bold',
marginBottom: '10px',
},
textBody: {
fontSize: '16px',
lineHeight: '1.5',
},
// Step Styles
stepsContainer: {
display: 'flex',
flexWrap: 'wrap',
gap: '10px', // Jarak antar langkah
position: 'relative',
},
step: {
flex: '1 1 16.6%', // Membagi langkah dalam 1/6 bagian dari lebar container
padding: '10px',
boxSizing: 'border-box',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
textAlign: 'center',
marginBottom: '10px',
position: 'relative',
},
stepNumberContainer: {
width: '40px',
height: '40px',
borderRadius: '50%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginBottom: '8px',
transition: 'background-color 0.3s ease',
},
stepNumber: {
fontSize: '16px',
color: '#fff',
fontWeight: 'bold',
},
stepDescription: {
fontSize: '14px',
lineHeight: '1.5',
color: '#333',
textAlign: 'center',
margin: '10px 0',
},
// Content Styles
contentContainer: {
marginTop: '20px',
padding: '20px',
},
infoBox: {
padding: '20px',
marginBottom: '20px',
},
descriptionList: {
listStyleType: 'disc',
paddingLeft: '20px',
color: '#333',
fontSize: '14px',
},
descriptionText: {
marginLeft: '0',
paddingLeft: '0',
fontSize: '14px',
color: '#333',
},
startButton: {
backgroundColor: '#0542cc',
color: '#fff',
padding: '10px 20px',
border: 'none',
borderRadius: '5px',
cursor: 'pointer',
marginTop: '15px',
},
checkboxContainer: {
display: 'flex',
alignItems: 'center',
marginBottom: '10px',
},
checkbox: {
marginRight: '10px',
},
checkboxLabel: {
color: '#0542cc',
fontSize: '14px',
},
backButton: {
padding: '10px 20px',
backgroundColor: '#fff', // Background color updated to white
color: '#000', // Text color set to black
border: '2px solid #0542cc', // Border color set to #0542cc
borderRadius: '5px',
cursor: 'pointer',
marginRight: '10px',
},
};

View File

@@ -0,0 +1,9 @@
import RegisterContent from "./RegisterContent";
import RegisterStep from "./RegisterStep";
import CreateSettings from "./CreateSettings";
export {
RegisterContent,
RegisterStep,
CreateSettings
}