Files
calendar/packages/features/timezone-buddy/components/HoverOverview.tsx
T
+16 67bb2ed798 feat: Availability slider for orgs (#10740)
* Init + get timezone + offset data agh

* Add 12/24h mode - style correctly

* User users timezone + working hours. Still some stuff to figure out

* Multiple working hours

* move calc to once per day

* Demo with two users and differnt timezones

* availabillity control tab via search params

* WIP hover overlay

* THIS WORKS ISH

* fix: multiple duration getSchedule calls [CAL-2336] (#10709)

Co-authored-by: Omar López <zomars@me.com>

* New Crowdin translations by Github Action

* fix: If the input type "Name" is selected, the label can't be changed from our default label "Your Name" (#10618)

Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>

* New Crowdin translations by Github Action

* test: Create unit tests for react components in packages/ui/components/form/step (#10442)

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* feat: element call app added (#10585)

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* New Crowdin translations by Github Action

* New Crowdin translations by Github Action

* fix: e2e test for rescheduling overlapping time (#10721)

Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* feat: mailhog fixture (#10606)

* feat: mailhog fixture

* fix: nodemailer to dispatch emails with e2e env

* fix: remove space from email subject

* feat: fixture getFirstEventAsOwner

* feat: assert email subjects

* fix: and enable dynamic booking test (#10642)

* fix and enable dynamic booking test

* remove page pause

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* fix: Broken team events if a user with the same name exists (#10724)

* fix: Broken team events if a user with the same name exists

* Fix tests + fix usernameList optionality

* Try to list calendars, if not continue (#10720)

Co-authored-by: Omar López <zomars@me.com>

* v3.1.9

* link to org settings (#10718)

* feat: app paypal payment (#8797)

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Omar López <zomars@me.com>

* fix: RTL issues on booking pages + email confirmation (#10526)

Co-authored-by: Peer Richelsen <peeroke@gmail.com>

* fix: merge conflict

* Fixing org slug (#10538)

* fix: paypal build fixes

* Fix avatar for org in Shell top (#10712)

* feat: add range of dates for availability over-ride (#10462)

* feat: add range of dates for availability over-ride

* chore: changed range select to multiple select

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* fix: border issue for time slots (#10577)

Co-authored-by: Raghul D <v-raghuld@microsoft.com>

* style: Fix text wrapping issue in button (#10725)

Co-authored-by: Omar López <zomars@me.com>

* New Crowdin translations by Github Action

* fix: App Install Dropdown Sort Properly [CAL-2285] (#10672)

Co-authored-by: Peer Richelsen <peeroke@gmail.com>

* fix: link escaping in booking page (#10360)

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* chore: fix refund i18n message (#10731)

* chore: remove tailwind-scrollbar warning (#10523)

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>

* New Crowdin translations by Github Action

* chore: Simplified date overrides (#10728)

* chore: Simplified date overrides

* Fixed a test that had a date override that wasn't at midnight utc

* Wrote test that showed a fixed Europe/Brussels

* Lint fix

* New Crowdin translations by Github Action

* Fix offset time + fetching correct dates

* Deal with awkward minute offsets

* remove store overhead

* Format H based on tz

* Cleanup store logic

* Cleanup

* Remove comments

* Remove comments

* Remove yarn.lock

* Dark mode & v-align text fixes

* Move ButtonGroup to the left to prevent chevron from jumping

* Shift based on timezone (non-hour) and have 15min granularity in hour display background color

---------

Co-authored-by: Leo Giovanetti <hello@leog.me>
Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Zain Gulbaz <zaingulbaz8@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Suyash Srivastava <suyashsrivastava5053@gmail.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Shivam Kalra <shivamkalra98@gmail.com>
Co-authored-by: alannnc <alannnc@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Pradumn Kumar <pradumn@tealfeed.com>
Co-authored-by: Raghul <123321540+Raghul18@users.noreply.github.com>
Co-authored-by: Raghul D <v-raghuld@microsoft.com>
Co-authored-by: ABDERRAHMANI IDRISSI HAMZA <97639117+idrissi-hamza@users.noreply.github.com>
Co-authored-by: Nafees Nazik <84864519+G3root@users.noreply.github.com>
Co-authored-by: Danila <daniil.demidovich@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-08-18 16:32:24 +00:00

150 lines
3.7 KiB
TypeScript

import { useState, useRef, useEffect, useMemo } from "react";
import { DAY_CELL_WIDTH } from "../constants";
function rounded(x: number, dayCellWidth: number) {
let n = Math.round(x / dayCellWidth);
n = Math.max(0, n);
n = Math.min(24, n);
return n * dayCellWidth;
}
function useElementBounding<T extends HTMLDivElement>(ref: React.RefObject<T>): DOMRect | null {
const [boundingRect, setBoundingRect] = useState<DOMRect | null>(null);
const observer = useRef<ResizeObserver | null>(null);
useEffect(() => {
const target = ref.current;
function updateBoundingRect() {
if (target) {
const rect = target.getBoundingClientRect();
setBoundingRect(rect);
}
}
updateBoundingRect();
observer.current = new ResizeObserver(updateBoundingRect);
observer.current.observe(target as Element);
return () => {
if (observer.current) {
observer.current.disconnect();
observer.current = null;
}
};
}, [ref]);
return boundingRect;
}
function useMouse() {
const [x, setX] = useState(0);
const [y, setY] = useState(0);
const [isPressed, setIsPressed] = useState(false);
useEffect(() => {
function handleMouseMove(event: MouseEvent) {
setX(event.clientX);
setY(event.clientY);
}
function handleMouseDown() {
setIsPressed(true);
}
function handleMouseUp() {
setIsPressed(false);
}
document.addEventListener("mousemove", handleMouseMove);
document.addEventListener("mousedown", handleMouseDown);
document.addEventListener("mouseup", handleMouseUp);
return () => {
document.removeEventListener("mousemove", handleMouseMove);
document.removeEventListener("mousedown", handleMouseDown);
document.removeEventListener("mouseup", handleMouseUp);
};
}, []);
return { x, y, isPressed };
}
export function HoverOverview() {
const top = useRef(0);
const bottom = useRef(0);
const edgeStart = useRef(0);
const edgeEnd = useRef(0);
const [leftEdge, setLeftEdge] = useState(0);
const [rightEdge, setRightEdge] = useState(0);
const [width, setWidth] = useState(0);
const { x, y, isPressed: pressed } = useMouse();
const el = useRef<HTMLDivElement | null>(null);
const box = useElementBounding(el);
useEffect(() => {
function updateEdge() {
const roundedX = rounded(x - (box?.left || 0), DAY_CELL_WIDTH);
edgeStart.current = roundedX;
edgeEnd.current = roundedX;
setLeftEdge(roundedX);
}
if (pressed) {
updateEdge();
}
}, [pressed, x, box]);
useEffect(() => {
if (pressed) {
const roundedX = rounded(x - (box?.left || 0), DAY_CELL_WIDTH);
edgeEnd.current = roundedX;
setRightEdge(roundedX);
}
}, [pressed, x, box]);
useEffect(() => {
setWidth(Math.abs(edgeStart.current - edgeEnd.current));
}, [edgeStart, edgeEnd]);
const position = useMemo(
() => ({
left: `${leftEdge}px`,
top: `${top}px`,
bottom: `${bottom}px`,
width: `${width}px`,
}),
[leftEdge, top, bottom, width]
);
const leftWhiteout = useMemo(
() => ({
left: "0",
top: `${top}px`,
bottom: `${bottom}px`,
width: `${leftEdge}px`,
}),
[leftEdge, top, bottom]
);
const rightWhiteout = useMemo(
() => ({
right: "0",
top: `${top}px`,
bottom: `${bottom}px`,
left: `${rightEdge}px`,
}),
[rightEdge, top, bottom]
);
return (
<div ref={el} className="absoulte inset-0 w-full">
<div className="bg-default/80 absolute" style={leftWhiteout} />
<div className="bg-default/80 absolute" style={rightWhiteout} />
<div className="border-emphasis border border-dashed" style={position} />
</div>
);
}