chore: use monorepo organization

This commit is contained in:
Rafael Taranto 2025-05-12 10:52:54 +01:00
parent deaf7d6ecc
commit a687827f7e
1099 changed files with 8184 additions and 11535 deletions

View file

@ -0,0 +1,138 @@
import {
add,
differenceInMonths,
format,
getDay,
getDaysInMonth,
isAfter,
isSameDay,
isSameMonth,
lastDayOfMonth,
startOfMonth,
startOfWeek,
sub
} from 'date-fns/fp'
import * as R from 'ramda'
import React, { useState } from 'react'
import Arrow from 'src/styling/icons/arrow/month_change.svg?react'
import RightArrow from 'src/styling/icons/arrow/month_change_right.svg?react'
import Tile from './Tile'
import classes from './Calendar.module.css'
const Calendar = ({ minDate, maxDate, handleSelect, ...props }) => {
const [currentDisplayedMonth, setCurrentDisplayedMonth] = useState(new Date())
const weekdays = Array.from(Array(7)).map((_, i) =>
format('EEEEE', add({ days: i }, startOfWeek(new Date())))
)
const monthLength = month => getDaysInMonth(month)
const monthdays = month => {
const lastMonth = sub({ months: 1 }, month)
const lastMonthRange = R.range(0, getDay(startOfMonth(month))).reverse()
const lastMonthDays = R.map(i =>
sub({ days: i }, lastDayOfMonth(lastMonth))
)(lastMonthRange)
const thisMonthRange = R.range(0, monthLength(month))
const thisMonthDays = R.map(i => add({ days: i }, startOfMonth(month)))(
thisMonthRange
)
const nextMonth = add({ months: 1 }, month)
const nextMonthRange = R.range(
0,
42 - lastMonthDays.length - thisMonthDays.length
)
const nextMonthDays = R.map(i => add({ days: i }, startOfMonth(nextMonth)))(
nextMonthRange
)
return R.concat(R.concat(lastMonthDays, thisMonthDays), nextMonthDays)
}
const getRow = (month, row) => monthdays(month).slice(row * 7 - 7, row * 7)
const handleNavPrev = currentMonth => {
const prevMonth = sub({ months: 1 }, currentMonth)
if (!minDate) setCurrentDisplayedMonth(prevMonth)
else {
setCurrentDisplayedMonth(
isSameMonth(minDate, prevMonth) ||
differenceInMonths(minDate, prevMonth) > 0
? prevMonth
: currentDisplayedMonth
)
}
}
const handleNavNext = currentMonth => {
const nextMonth = add({ months: 1 }, currentMonth)
if (!maxDate) setCurrentDisplayedMonth(nextMonth)
else {
setCurrentDisplayedMonth(
isSameMonth(maxDate, nextMonth) ||
differenceInMonths(nextMonth, maxDate) > 0
? nextMonth
: currentDisplayedMonth
)
}
}
return (
<div className={classes.wrapper}>
<div className={classes.navbar}>
<button
className={classes.button}
onClick={() => handleNavPrev(currentDisplayedMonth)}>
<Arrow />
</button>
<span>
{`${format('MMMM', currentDisplayedMonth)} ${format(
'yyyy',
currentDisplayedMonth
)}`}
</span>
<button
className={classes.button}
onClick={() => handleNavNext(currentDisplayedMonth)}>
<RightArrow />
</button>
</div>
<table className={classes.table}>
<thead>
<tr>
{weekdays.map((day, key) => (
<th key={key}>{day}</th>
))}
</tr>
</thead>
<tbody>
{R.range(1, 8).map((row, key) => (
<tr key={key}>
{getRow(currentDisplayedMonth, row).map((day, key) => (
<td key={key} onClick={() => handleSelect(day)}>
<Tile
isDisabled={
(maxDate && isAfter(maxDate, day)) ||
(minDate && isAfter(day, minDate))
}
isLowerBound={isSameDay(props.from, day)}
isUpperBound={isSameDay(props.to, day)}
isBetween={
isAfter(props.from, day) && isAfter(day, props.to)
}>
{format('d', day)}
</Tile>
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
)
}
export default Calendar

View file

@ -0,0 +1,66 @@
.wrapper {
display: flex;
flex-direction: column;
align-items: center;
}
.button {
outline: none;
}
.navbar {
font-size: 14px;
font-family: var(--museo);
font-weight: 500;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 15px 15px;
color: var(--zodiac);
}
.navbar button {
display: flex;
align-items: center;
padding: 0;
border: none;
background-color: var(--zircon);
cursor: pointer;
border-radius: 50%;
width: 20px;
height: 20px;
position: relative;
overflow: hidden;
}
.navbar button svg {
position: absolute;
left: 0;
}
.table {
border-collapse: collapse;
width: 100%;
color: var(--zodiac);
}
.table tr:first-child {
padding-left: 5px;
}
.table tr:last-child {
padding-right: 5px;
}
.table th,
.table td {
margin: 0;
padding: 3px 0 3px 0;
}
.table th {
font-size: 13px;
font-family: var(--museo);
font-weight: 700;
}

View file

@ -0,0 +1,59 @@
import classnames from 'classnames'
import { compareAsc, differenceInDays, set } from 'date-fns/fp'
import * as R from 'ramda'
import React, { useState, useEffect } from 'react'
import Calendar from './Calendar'
const DateRangePicker = ({ minDate, maxDate, className, onRangeChange }) => {
const [from, setFrom] = useState(null)
const [to, setTo] = useState(null)
useEffect(() => {
onRangeChange(from, to)
}, [from, onRangeChange, to])
const handleSelect = day => {
if (
(maxDate && compareAsc(maxDate, day) > 0) ||
(minDate && differenceInDays(day, minDate) > 0)
)
return
if (from && !to) {
if (differenceInDays(from, day) >= 0) {
setTo(
set({ hours: 23, minutes: 59, seconds: 59, milliseconds: 999 }, day)
)
} else {
setTo(
set(
{ hours: 23, minutes: 59, seconds: 59, milliseconds: 999 },
R.clone(from)
)
)
setFrom(day)
}
return
}
setFrom(day)
setTo(null)
}
return (
<>
<div className={classnames('bg-white rounded-xl', className)}>
<Calendar
from={from}
to={to}
minDate={minDate}
maxDate={maxDate}
handleSelect={handleSelect}
/>
</div>
</>
)
}
export default DateRangePicker

View file

@ -0,0 +1,41 @@
import classnames from 'classnames'
import React from 'react'
import classes from './Tile.module.css'
const Tile = ({
isLowerBound,
isUpperBound,
isBetween,
isDisabled,
children
}) => {
const selected = isLowerBound || isUpperBound
const rangeClasses = {
[classes.between]: isBetween && !(isLowerBound && isUpperBound),
[classes.lowerBound]: isLowerBound && !isUpperBound,
[classes.upperBound]: isUpperBound && !isLowerBound
}
const buttonWrapperClasses = {
[classes.wrapper]: true,
[classes.selected]: selected
}
const buttonClasses = {
[classes.button]: true,
[classes.disabled]: isDisabled
}
return (
<div className={classes.wrapper}>
<div className={classnames(rangeClasses)} />
<div className={classnames(buttonWrapperClasses)}>
<button className={classnames(buttonClasses)}>{children}</button>
</div>
</div>
)
}
export default Tile

View file

@ -0,0 +1,53 @@
.wrapper {
height: 26px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.button {
outline: none;
font-size: 13px;
font-family: var(--museo);
font-weight: 500;
border: none;
cursor: pointer;
background-color: transparent;
color: var(--zodiac);
z-index: 2;
}
.lowerBound {
left: 50%;
}
.upperBound {
right: 50%;
}
.selected {
width: 26px;
height: 26px;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--spring2);
border-radius: 50%;
position: absolute;
z-index: 1;
}
.between {
position: absolute;
width: 100%;
height: 100%;
z-index: 0;
background-color: var(--spring3);
}
.disabled {
color: var(--dust);
cursor: default;
}