Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat(cc-widgets): Style station login component #404

Merged
merged 15 commits into from
Mar 6, 2025
Merged
2 changes: 1 addition & 1 deletion packages/contact-center/cc-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,4 @@
"react": ">=18.3.1",
"react-dom": ">=18.3.1"
}
}
}
2 changes: 1 addition & 1 deletion packages/contact-center/cc-widgets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,4 @@
"^.+\\.(css|less|scss)$": "babel-jest"
}
}
}
}
2 changes: 1 addition & 1 deletion packages/contact-center/station-login/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,4 @@
"^.+\\.(css|less|scss)$": "babel-jest"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React, {useEffect, useRef} from 'react';
import React, {useEffect, useState, useRef, useCallback} from 'react';
import {StationLoginPresentationalProps} from './station-login.types';
import './station-login.style.scss';
import {MULTIPLE_SIGN_IN_ALERT_MESSAGE, MULTIPLE_SIGN_IN_ALERT_TITLE} from './constants';
import {ButtonPill} from '@momentum-ui/react-collaboration';
import {ButtonPill, Text, SelectNext, TextInput} from '@momentum-ui/react-collaboration';
import {Item} from '@react-stately/collections';
import {Icon} from '@momentum-design/components/dist/react';

const StationLoginPresentational: React.FunctionComponent<StationLoginPresentationalProps> = (props) => {
const {
Expand All @@ -18,145 +20,170 @@ const StationLoginPresentational: React.FunctionComponent<StationLoginPresentati
deviceType,
showMultipleLoginAlert,
handleContinue,
} = props; // TODO: Use the loginSuccess, loginFailure, logoutSuccess props returned fromthe API response via helper file to reflect UI changes
} = props;

const modalRef = useRef<HTMLDialogElement>(null);
const [dialNumberValue, setDialNumberValue] = useState<string>('');
const [agentLoginValue, setAgentLoginValue] = useState<string>('');
const [teamsValue, setTeamsValue] = useState<string>('');
const [isDialNumberDisabled, setIsDialNumberDisabled] = useState<boolean>(false);

useEffect(() => {
const teamsDropdown = document.getElementById('teamsDropdown') as HTMLSelectElement;
const agentLogin = document.querySelector('#LoginOption') as HTMLSelectElement;
const dialNumber = document.querySelector('#dialNumber') as HTMLInputElement;
if (teamsDropdown) {
teamsDropdown.innerHTML = '';
if (teams) {
teams.forEach((team) => {
const option = document.createElement('option');
option.value = team.id;
option.text = team.name;
teamsDropdown.add(option);
});
setTeam(teamsDropdown.value);
dialNumber.value = '';
dialNumber.disabled = true;
}
}
if (loginOptions.length > 0) {
loginOptions.forEach((options) => {
const option = document.createElement('option');
option.text = options;
option.value = options;
agentLogin.add(option);
});
if (agentLogin && deviceType) {
agentLogin.value = deviceType;
}
const firstOption = loginOptions[0];
setAgentLoginValue('0');
setDeviceType(firstOption);
}
}, [teams, loginOptions]);
}, [loginOptions, setDeviceType]);

useEffect(() => {
const modal = modalRef.current;
if (showMultipleLoginAlert && modal) {
modal.showModal();
if (teams.length > 0) {
const firstTeam = teams[0].id;
setTeamsValue(firstTeam);
setTeam(firstTeam);
}
}, [showMultipleLoginAlert, modalRef]);
}, [teams, setTeam]);

useEffect(() => {
if (!isAgentLoggedIn) return;
const agentLogin = document.querySelector('#LoginOption') as HTMLSelectElement;
if (agentLogin && !agentLogin.value) {
setDeviceType(deviceType);
agentLogin.value = deviceType;
relogin();
if (showMultipleLoginAlert && modalRef.current) {
modalRef.current.showModal();
}
}, [isAgentLoggedIn]);
}, [showMultipleLoginAlert]);

const selectLoginOption = (event: {target: {value: string}}) => {
const dialNumber = document.querySelector('#dialNumber') as HTMLInputElement;
const deviceType = event.target.value;
useEffect(() => {
if (!isAgentLoggedIn || !deviceType) return;
setDeviceType(deviceType);
if (deviceType === 'AGENT_DN' || deviceType === 'EXTENSION') {
dialNumber.disabled = false;
} else {
dialNumber.disabled = true;
}
};
setAgentLoginValue(loginOptions.indexOf(deviceType).toString());
relogin();
}, [isAgentLoggedIn, deviceType, loginOptions, setDeviceType, relogin]);

const continueClicked = () => {
const modal = modalRef.current;
if (modal) {
modal.close();
const selectLoginOption = useCallback(
(key: string) => {
const index = parseInt(key, 10);
if (!isNaN(index) && loginOptions[index]) {
setAgentLoginValue(key);
setDeviceType(loginOptions[index]);
setIsDialNumberDisabled(!['AGENT_DN', 'EXTENSION'].includes(loginOptions[index]));
}
},
[loginOptions, setDeviceType]
);

const continueClicked = useCallback(() => {
if (modalRef.current) {
modalRef.current.close();
handleContinue();
}
};
}, [handleContinue]);

const updateDN = useCallback(
(value: string) => {
setDialNumberValue(value);
setDialNumber(value);
},
[setDialNumber]
);

function updateDN() {
const dialNumber = document.querySelector('#dialNumber') as HTMLInputElement;
setDialNumber(dialNumber.value);
}
const updateTeam = useCallback(
(value: string) => {
setTeamsValue(value);
setTeam(value);
},
[setTeam]
);

return (
<>
{showMultipleLoginAlert && (
<dialog ref={modalRef} className="modal">
<h2>{MULTIPLE_SIGN_IN_ALERT_TITLE}</h2>
<p>{MULTIPLE_SIGN_IN_ALERT_MESSAGE}</p>
<div className="modal-content">
<button id="ContinueButton" data-testid="ContinueButton" onClick={continueClicked}>
Continue
</button>
</div>
</dialog>
)}
<div className="box">
<dialog ref={modalRef} className="modal" open={showMultipleLoginAlert}>
<h2>{MULTIPLE_SIGN_IN_ALERT_TITLE}</h2>
<p>{MULTIPLE_SIGN_IN_ALERT_MESSAGE}</p>
<div className="modal-content">
<button id="ContinueButton" data-testid="ContinueButton" onClick={continueClicked}>
Continue
</button>
</div>
</dialog>
<div className="box station-login">
<section className="section-box">
<fieldset className="fieldset">
<legend className="legend-box">Agent</legend>
<div style={{display: 'flex', flexDirection: 'column', flexGrow: 1}}>
<div style={{display: 'flex', gap: '1rem'}}>
<fieldset
style={{
border: '1px solid #ccc',
borderRadius: '5px',
padding: '10px',
marginBottom: '20px',
flex: 0.69,
}}
>
<legend className="legend-box">Select Team</legend>
<select id="teamsDropdown" className="select">
Teams
</select>
</fieldset>
<fieldset className="fieldset">
<legend className="legend-box">Agent Login</legend>
<select name="LoginOption" id="LoginOption" className="select" onChange={selectLoginOption}>
<option value="" hidden>
Choose Agent Login Option...
</option>
</select>
<input
className="input"
id="dialNumber"
name="dialNumber"
placeholder="Extension/Dial Number"
type="text"
onInput={updateDN}
/>
{isAgentLoggedIn ? (
<ButtonPill id="logoutAgent" onPress={logout} color="cancel">
Logout
</ButtonPill>
) : (
<ButtonPill id="AgentLogin" onPress={login} color="join">
Login
</ButtonPill>
)}
</fieldset>
</div>
<Text tagName={'span'} type="heading-small-bold">
Set your interaction preferences
</Text>
</fieldset>
<fieldset className="fieldset">
<legend id="agent-login-label">Handle calls using</legend>
<div className="select-container">
<SelectNext
id="login-option"
direction="bottom"
showBorder
aria-labelledby="agent-login-label"
items={loginOptions.map((name, id) => ({key: id.toString(), name}))}
selectedKey={agentLoginValue}
onSelectionChange={selectLoginOption}
className="station-login-select"
>
{(item) => (
<Item textValue={item.name} key={item.key}>
<Text className="state-name" tagName={'small'}>
{item.name}
</Text>
</Item>
)}
</SelectNext>
<Icon className="select-arrow-icon" name="arrow-down-bold" title="" />
</div>
</fieldset>
<fieldset className="fieldset">
<legend id="dial-number-label">Dial number</legend>
<TextInput
clearAriaLabel="Clear"
aria-labelledby="dial-number-label"
placeholder="Extension/Dial Number"
onChange={updateDN}
value={dialNumberValue}
isDisabled={isDialNumberDisabled}
/>
</fieldset>
<fieldset className="fieldset">
<legend id="team-label">Your team</legend>
<div className="select-container">
<SelectNext
id="teams-dropdown"
direction="bottom"
showBorder
aria-labelledby="team-label"
items={teams}
selectedKey={teamsValue}
onSelectionChange={updateTeam}
className="station-login-select"
>
{(item) => (
<Item textValue={item.name} key={item.id}>
<Text className="state-name" tagName={'small'}>
{item.name}
</Text>
</Item>
)}
</SelectNext>
<Icon className="select-arrow-icon" name="arrow-down-bold" title="" />
</div>
</fieldset>
<div className="btn-container">
{isAgentLoggedIn ? (
<ButtonPill id="logoutAgent" onPress={logout} color="cancel">
Logout
</ButtonPill>
) : (
<ButtonPill id="AgentLogin" onPress={login} color="join">
Save & Continue
</ButtonPill>
)}
</div>
</section>
</div>
</>
);
};

export default StationLoginPresentational;
Loading