fix: date picker ui-fix (#3382)

Co-authored-by: Jonas Höbenreich <64426524+jonas-hoebenreich@users.noreply.github.com>
Co-authored-by: Vinay Kumar Maheshwaram <54681400+sudovinay01@users.noreply.github.com>
Co-authored-by: Sharad Kushwaha <123795629+SharadK10@users.noreply.github.com>
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
Co-authored-by: Chase Nelson <Chase.a.nelson@gmail.com>
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
Co-authored-by: Johannes <johannes@formbricks.com>
This commit is contained in:
Sai Suhas Sawant
2024-10-31 09:37:42 +05:30
committed by GitHub
parent 297f349b45
commit 705f55176f
3 changed files with 146 additions and 36 deletions

View File

@@ -334,7 +334,7 @@ export const ResponseOptionsCard = ({
description="Automatically release the survey at the beginning of the day (UTC)."
childBorder={true}>
<div className="p-4">
<DatePicker date={runOnDate} handleDateChange={handleRunOnDateChange} />
<DatePicker date={runOnDate} updateSurveyDate={handleRunOnDateChange} />
</div>
</AdvancedOptionToggle>
{/* Close Survey on Date */}
@@ -346,7 +346,7 @@ export const ResponseOptionsCard = ({
description="Automatically closes the survey at the beginning of the day (UTC)."
childBorder={true}>
<div className="p-4">
<DatePicker date={closeOnDate} handleDateChange={handleCloseOnDateChange} />
<DatePicker date={closeOnDate} updateSurveyDate={handleCloseOnDateChange} />
</div>
</AdvancedOptionToggle>

View File

@@ -1,54 +1,111 @@
"use client";
import { format } from "date-fns";
import { addDays } from "date-fns";
import { CalendarIcon } from "lucide-react";
import { useRef } from "react";
import { SelectSingleEventHandler } from "react-day-picker";
import { CalendarCheckIcon, CalendarIcon } from "lucide-react";
import { useRef, useState } from "react";
import Calendar from "react-calendar";
import { cn } from "@formbricks/lib/cn";
import { Button } from "../Button";
import { Calendar } from "../Calendar";
import { Popover, PopoverContent, PopoverTrigger } from "../Popover";
import "./styles.css";
export const DatePicker = ({
date,
handleDateChange,
}: {
date?: Date | null;
handleDateChange: (date?: Date) => void;
}) => {
let formattedDate = date ? new Date(date) : undefined;
const getOrdinalSuffix = (day: number) => {
if (day > 3 && day < 21) return "th"; // 11th, 12th, 13th, etc.
switch (day % 10) {
case 1:
return "st";
case 2:
return "nd";
case 3:
return "rd";
default:
return "th";
}
};
interface DatePickerProps {
date: Date | null;
updateSurveyDate: (date: Date) => void;
}
export const DatePicker = ({ date, updateSurveyDate }: DatePickerProps) => {
const [value, onChange] = useState<Date | undefined>(date ? new Date(date) : undefined);
const [formattedDate, setFormattedDate] = useState<string | undefined>(
date ? format(new Date(date), "do MMM, yyyy") : undefined
);
const [isOpen, setIsOpen] = useState(false);
const btnRef = useRef<HTMLButtonElement>(null);
const handleDateSelect: SelectSingleEventHandler = (date) => {
btnRef?.current?.click();
handleDateChange(date);
const onDateChange = (date: Date) => {
if (date) {
updateSurveyDate(date);
const day = date.getDate();
const ordinalSuffix = getOrdinalSuffix(day);
const formatted = format(date, `d'${ordinalSuffix}' MMM, yyyy`);
setFormattedDate(formatted);
onChange(date);
setIsOpen(false);
}
};
return (
<Popover>
<Popover open={isOpen} onOpenChange={setIsOpen}>
<PopoverTrigger asChild>
<Button
variant={"minimal"}
className={cn(
"w-[280px] justify-start border border-slate-300 bg-white text-left font-normal",
!formattedDate && "text-muted-foreground"
)}
ref={btnRef}>
<CalendarIcon className="mr-2 h-4 w-4" />
{formattedDate ? format(formattedDate, "PPP") : <span>Pick a date</span>}
</Button>
{formattedDate ? (
<Button
variant={"minimal"}
className={cn(
"w-[280px] justify-start border border-slate-300 bg-white text-left font-normal transition-all ease-in hover:bg-slate-300",
!formattedDate && "text-muted-foreground bg-slate-800"
)}
ref={btnRef}>
<CalendarCheckIcon className="mr-2 h-4 w-4" />
{formattedDate}
</Button>
) : (
<Button
variant={"minimal"}
className={cn(
"w-[280px] justify-start border border-slate-300 bg-white text-left font-normal hover:bg-slate-300",
!formattedDate && "text-muted-foreground"
)}
onClick={() => setIsOpen(true)}
ref={btnRef}>
<CalendarIcon className="mr-2 h-4 w-4" />
<span>Pick a date</span>
</Button>
)}
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<PopoverContent align="start" className="min-w-96 rounded-lg px-4 py-3">
<Calendar
autoFocus
mode="single"
selected={formattedDate}
disabled={{
before: addDays(new Date(), 1),
value={value}
onChange={(date) => onDateChange(date as Date)}
minDate={new Date()}
className="!border-0"
tileClassName={({ date }: { date: Date }) => {
const baseClass =
"hover:fb-bg-input-bg-selected fb-rounded-custom fb-h-9 fb-p-0 fb-mt-1 fb-font-normal fb-text-heading aria-selected:fb-opacity-100 focus:fb-ring-2 focus:fb-bg-slate-200";
// today's date class
if (
date.getDate() === new Date().getDate() &&
date.getMonth() === new Date().getMonth() &&
date.getFullYear() === new Date().getFullYear()
) {
return `${baseClass} !fb-bg-brand !fb-border-border-highlight !fb-text-heading focus:fb-ring-2 focus:fb-bg-slate-200`;
}
// active date class
if (
date.getDate() === value?.getDate() &&
date.getMonth() === value?.getMonth() &&
date.getFullYear() === value?.getFullYear()
) {
return `${baseClass} !fb-bg-brand !fb-border-border-highlight !fb-text-heading`;
}
return baseClass;
}}
onSelect={handleDateSelect}
showNeighboringMonth={false}
/>
</PopoverContent>
</Popover>

View File

@@ -0,0 +1,53 @@
.react-calendar__navigation button {
margin: 1% !important ;
border-radius: 6%;
}
.react-calendar__navigation button:disabled {
background-color: var(--slate-100) !important;
color: var(--slate-300) !important;
cursor: not-allowed !important;
pointer-events: none !important;
}
.react-calendar__navigation button:enabled:hover,
.react-calendar__navigation button:enabled:focus {
background-color: var(--slate-200) !important;
}
.react-calendar__month-view__weekdays {
text-decoration-style: dotted !important;
text-decoration: underline;
}
.react-calendar__month-view__days__day--weekend {
color: var(--fb-brand) !important;
}
.react-calendar__tile:disabled {
background-color: var(--slate-100) !important;
color: var(--slate-400) !important;
cursor: not-allowed !important;
pointer-events: none !important;
}
.react-calendar__tile:enabled:hover,
.react-calendar__tile:enabled:focus {
background-color: var(--slate-200) !important;
color: var(--slate-900) !important;
}
.react-calendar__tile--now {
background: none !important;
}
.react-calendar__tile .react-calendar__year-view__months__month {
margin: 20px !important;
background-color: var(--slate-100) !important;
color: var(--slate-900) !important;
}
.react-calendar__tile--hasActive {
background-color: var(--fb-brand) !important;
color: white !important;
border-radius: 6% !important;
}