Skip to content

Commit

Permalink
Upgraded to latest version of react router and primereact. removed ti…
Browse files Browse the repository at this point in the history
…me picker dependency as the library is outdated.
  • Loading branch information
shridhar-tl committed Dec 19, 2024
1 parent 8bd5db0 commit b6cc637
Show file tree
Hide file tree
Showing 9 changed files with 270 additions and 134 deletions.
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,15 @@
"patternomaly": "^1.3.2",
"primeflex": "^3.3.1",
"primeicons": "^7.0.0",
"primereact": "^9.6.4",
"primereact": "^10.8.5",
"queue": "^7.0.0",
"rc-time-picker": "^3.7.3",
"react": "^18.3.1",
"react-bootstrap-daterangepicker": "^8.0.0",
"react-controls": "github:shridhar-tl/react-controls",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.23.1",
"react-router-dom": "^7.0.2",
"react-scripts": "github:shridhar-tl/react-scripts",
"static-eval": "^2.1.1",
"zustand": "^5.0.2"
Expand Down Expand Up @@ -218,4 +217,4 @@
"node_modules/jspdf/dist/"
]
}
}
}
5 changes: 0 additions & 5 deletions src/controls/Common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,6 @@ Commented on 25-Jan-2023
}
}*/

/* Time picker */
.rc-time-picker {
width: 110px;
}

/* Chips */

.p-chips {
Expand Down
207 changes: 159 additions & 48 deletions src/controls/TimePicker.jsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,178 @@
import React, { PureComponent } from 'react';
import Picker from 'rc-time-picker';
import "rc-time-picker/assets/index.css";
import moment from "moment";
import React, { useState, useEffect, useRef } from 'react';
import moment from 'moment';
import './TimePicker.scss';

const disabledHours = [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23];
const defaultDisabledHours = [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23];

class TimePicker extends PureComponent {
state = {};
const TimePicker = ({
value,
mode = 'number',
className = '',
disabled = false,
placeholder = "Choose time",
disabledHours = defaultDisabledHours,
hideDisabledHours = true,
onChange,
field
}) => {
const [timeValue, setTimeValue] = useState(null);
const [isPopoverVisible, setIsPopoverVisible] = useState(false);
const [selectedHour, setSelectedHour] = useState(null);
const [selectedMinute, setSelectedMinute] = useState(null);
const popoverRef = useRef();

static getDerivedStateFromProps(nextProps, prevState) {
let { value } = nextProps;
let newState = null;

if (!prevState || prevState.value !== value) {
newState = { value };
if (value) {
const curDate = moment();
if (nextProps.mode === "string") {
// ToDo: Yet to implement
}
else {
value = value.toString().split('.');
curDate.set({ h: value[0], m: parseInt(Math.round(60 * `.${(value[1] || 0)}`)) || 0 });
// Sync state with incoming props.value
useEffect(() => {
if (value !== undefined) {
if (mode === "string") {
// ToDo: Implement string mode handling if needed
// Example: setTimeValue(moment(value, 'HH:mm'));
// For now, it's left unimplemented as per original code
setTimeValue(null);
} else {
if (value !== null && value !== undefined) {
const h = Math.floor(value);
const m = Math.round((value - h) * 60);
const curDate = moment().set({ hour: h, minute: m, second: 0, millisecond: 0 });
setTimeValue(curDate);
setSelectedHour(h);
setSelectedMinute(m);
} else {
setTimeValue(null);
setSelectedHour(null);
setSelectedMinute(null);
}
newState.timeValue = curDate;
}
else {
newState.timeValue = null;
}
}, [value, mode]);

// Handle clicks outside the popover to close it
useEffect(() => {
const handleClickOutside = (event) => {
if (popoverRef.current && !popoverRef.current.contains(event.target)) {
setIsPopoverVisible(false);
}
};

if (isPopoverVisible) {
document.addEventListener('mousedown', handleClickOutside);
} else {
document.removeEventListener('mousedown', handleClickOutside);
}

return newState;
}
// Cleanup on unmount
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [isPopoverVisible]);

onChange = (timeValue) => {
const value = this.getValue(timeValue);
this.setState({ timeValue, value });
this.props.onChange(value, this.props.field);
// Toggle popover visibility
const togglePopover = () => {
if (!disabled) {
setIsPopoverVisible((prev) => !prev);
}
};

getValue(timeValue) {
if (!timeValue) { return null; }
// Handle hour selection
const handleHourSelect = (hour) => {
setSelectedHour(hour);
if (selectedMinute !== null) {
updateTime(hour, selectedMinute);
}
};

const { mode } = this.props;
if (mode === "string") {
// ToDo: Yet to implement
// Handle minute selection
const handleMinuteSelect = (minute) => {
setSelectedMinute(minute);
if (selectedHour !== null) {
updateTime(selectedHour, minute);
}
else {
return timeValue.hour() + (timeValue.minute() / 60);
};

// Update timeValue and notify parent via onChange
const updateTime = (hour, minute) => {
const newTime = moment().set({ hour, minute, second: 0, millisecond: 0 });
setTimeValue(newTime);
const newValue = hour + (minute / 60);
if (onChange) {
onChange(newValue, field);
}
}
setIsPopoverVisible(false);
};

checkDisabled = () => disabledHours;
// Display value in the input field
const getDisplayValue = () => {
if (timeValue) {
return timeValue.format('HH:mm');
}
return '';
};

render() {
const { state: { timeValue }, props: { className, disabled, placeholder = "Choose time" } } = this;
// Render list of hour options
const renderHours = () => {
const hours = [];
for (let h = 0; h < 24; h++) {
const isDisabled = disabledHours.includes(h);
if (hideDisabledHours && isDisabled) {
continue;
}
hours.push(
<div
key={h}
className={`time-picker-option ${isDisabled ? 'disabled' : ''} ${selectedHour === h ? 'selected' : ''}`}
onClick={() => {
if (!isDisabled) {
handleHourSelect(h);
}
}}
>
{h.toString().padStart(2, '0')}
</div>
);
}
return hours;
};

// Render list of minute options
const renderMinutes = () => {
const minutes = [];
for (let m = 0; m < 60; m++) {
minutes.push(
<div
key={m}
className={`time-picker-option ${selectedMinute === m ? 'selected' : ''}`}
onClick={() => handleMinuteSelect(m)}
>
{m.toString().padStart(2, '0')}
</div>
);
}
return minutes;
};

return (
<Picker defaultValue={timeValue} className={className} disabled={disabled}
showSecond={false} inputReadOnly={false} placeholder={placeholder}
onChange={this.onChange} disabledHours={this.checkDisabled} hideDisabledOptions={true} />
);
}
}
return (
<div className={`time-picker-wrapper ${className}`} ref={popoverRef}>
<input
type="text"
className="time-picker-input"
value={getDisplayValue()}
onClick={togglePopover}
readOnly
disabled={disabled}
placeholder={placeholder}
/>
{isPopoverVisible && (
<div className="time-picker-popover">
<div className="time-picker-list hours">
{renderHours()}
</div>
<div className="time-picker-list minutes">
{renderMinutes()}
</div>
</div>
)}
</div>
);
};

export default TimePicker;
72 changes: 72 additions & 0 deletions src/controls/TimePicker.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
.time-picker-wrapper {
position: relative;
display: inline-block;
width: 86px;

.time-picker-input {
width: 100%;
padding: 2px 6px;
box-sizing: border-box;
cursor: pointer;
border: 1px solid #ccc;
border-radius: 4px;

&:disabled {
background-color: #f5f5f5;
cursor: not-allowed;
}
}

.time-picker-popover {
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
background: white;
border: 1px solid #ccc;
display: flex;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
margin-top: 4px;
border-radius: 4px;
}

.time-picker-list {
max-height: 200px;
overflow-y: auto;
padding: 0;
display: flex;
flex-direction: column;
user-select: none;

&.hours {
border-right: 1px solid #eee;
width: 42px;
}

&.minutes {
width: 42px;
}

.time-picker-option {
padding: 1px 4px;
margin-bottom: 4px;
text-align: center;
border-radius: 4px;
cursor: pointer;

&.disabled {
color: #999;
cursor: not-allowed;
}

&.selected {
background-color: #1890ff;
color: white;
}

&:hover:not(.disabled) {
background-color: #f0f0f0;
}
}
}
}
18 changes: 0 additions & 18 deletions src/scss/_custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,6 @@ body {
/* #endregion */

/* #region Padding related styles */
.no-b-pad {
padding-bottom: 0 !important;
}

.no-t-pad {
padding-top: 0 !important;
}

.no-pad {
padding: 0 !important;
}
Expand All @@ -73,11 +65,6 @@ body {
padding-bottom: 8px;
}

.pad-h-8 {
padding-left: 8px !important;
padding-right: 8px !important;
}

.pad-8 {
padding: 8px;
}
Expand Down Expand Up @@ -138,11 +125,6 @@ body {
width: 26px;
}

.img-x28 {
height: 28px;
width: 28px;
}

.img-x32 {
height: 32px;
width: 32px;
Expand Down
Loading

0 comments on commit b6cc637

Please sign in to comment.