feat: create DayTabs date carousel component
This commit is contained in:
+13
-12
@@ -8,25 +8,26 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.15.0",
|
||||
"primereact": "^10.0.0",
|
||||
"primeicons": "^6.0.0",
|
||||
"leaflet": "^1.7.1",
|
||||
"@tanstack/react-query": "^5.28.0",
|
||||
"axios": "^1.6.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"i18next": "^23.7.0",
|
||||
"i18next-http-backend": "^2.4.0",
|
||||
"leaflet": "^1.7.1",
|
||||
"primeicons": "^6.0.0",
|
||||
"primereact": "^10.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-i18next": "^13.5.0",
|
||||
"axios": "^1.6.0",
|
||||
"@tanstack/react-query": "^5.28.0",
|
||||
"react-router-dom": "^6.15.0",
|
||||
"zustand": "^4.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^5.0.0",
|
||||
"@vitejs/plugin-react": "^4.2.0",
|
||||
"typescript": "^5.3.0",
|
||||
"@types/react": "^18.2.0",
|
||||
"@types/react-dom": "^18.2.0",
|
||||
"sass": "^1.69.0"
|
||||
"@vitejs/plugin-react": "^4.2.0",
|
||||
"sass": "^1.69.0",
|
||||
"typescript": "^5.3.0",
|
||||
"vite": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
.day-tabs {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.day-tabs__day {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 12px;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 4px;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
min-width: 60px;
|
||||
|
||||
&:hover {
|
||||
border-color: #1976d2;
|
||||
color: #1976d2;
|
||||
}
|
||||
|
||||
&--active {
|
||||
background: #1976d2;
|
||||
color: white;
|
||||
border-color: #1976d2;
|
||||
}
|
||||
}
|
||||
|
||||
.day-tabs__day-name {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.day-tabs__day-num {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import React from 'react'
|
||||
import { Carousel } from 'primereact/carousel'
|
||||
import { format, addDays, startOfDay } from 'date-fns'
|
||||
import './day-tabs.scss'
|
||||
|
||||
export interface DayTabsProps {
|
||||
selectedDate: Date
|
||||
onDateSelect: (date: Date) => void
|
||||
minDate?: Date
|
||||
maxDate?: Date
|
||||
'data-testid'?: string
|
||||
}
|
||||
|
||||
export const DayTabs: React.FC<DayTabsProps> = ({
|
||||
selectedDate,
|
||||
onDateSelect,
|
||||
'data-testid': dataTestId,
|
||||
}) => {
|
||||
|
||||
const getDays = () => {
|
||||
const days = []
|
||||
for (let i = 0; i < 7; i++) {
|
||||
days.push(startOfDay(addDays(new Date(), i)))
|
||||
}
|
||||
return days
|
||||
}
|
||||
|
||||
const days = getDays()
|
||||
|
||||
const dayItemTemplate = (day: Date) => {
|
||||
const isSelected = format(day, 'yyyy-MM-dd') === format(selectedDate, 'yyyy-MM-dd')
|
||||
const dayName = format(day, 'EEE')
|
||||
const dayNum = format(day, 'd')
|
||||
|
||||
return (
|
||||
<button
|
||||
className={`day-tabs__day ${isSelected ? 'day-tabs__day--active' : ''}`}
|
||||
onClick={() => onDateSelect(day)}
|
||||
data-testid={`day-tab-${format(day, 'yyyy-MM-dd')}`}
|
||||
>
|
||||
<div className="day-tabs__day-name">{dayName}</div>
|
||||
<div className="day-tabs__day-num">{dayNum}</div>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="day-tabs" data-testid={dataTestId || 'day-tabs'}>
|
||||
<Carousel
|
||||
value={days}
|
||||
itemTemplate={dayItemTemplate}
|
||||
numScroll={3}
|
||||
numVisible={7}
|
||||
circular={false}
|
||||
showNavigators={true}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export { DayTabs } from './day-tabs'
|
||||
export type { DayTabsProps } from './day-tabs'
|
||||
Reference in New Issue
Block a user