From 3dc073542ca414fffd654d8371ee931dfde9064e Mon Sep 17 00:00:00 2001 From: Sophia Date: Sun, 26 Feb 2023 18:15:46 -0500 Subject: [PATCH] Add Modals (#175) --- src/components/ComparisonContainer/index.tsx | 238 ++++++++++++++---- .../ComparisonContainer/stylesheet.scss | 42 ++-- src/components/ComparisonPanel/index.tsx | 19 +- 3 files changed, 214 insertions(+), 85 deletions(-) diff --git a/src/components/ComparisonContainer/index.tsx b/src/components/ComparisonContainer/index.tsx index 777a835f..58e0a964 100644 --- a/src/components/ComparisonContainer/index.tsx +++ b/src/components/ComparisonContainer/index.tsx @@ -4,6 +4,7 @@ import { ScheduleContext } from '../../contexts'; import { faPencil, faCircleXmark } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import Button, { ButtonProps } from '../Button'; +import Modal from '../Modal'; import './stylesheet.scss'; export type SharedSchedule = { @@ -18,6 +19,13 @@ export type SharedSchedule = { export default function ComparisonContainer(): React.ReactElement { const [compare, setCompare] = useState(false); const [selected, setSelected] = useState([]); + const [deleteConfirm, setDeleteConfirm] = useState<{ + id: string; + type: string; + name: string; + owner?: string; + } | null>(null); + const [{ allVersionNames }, { deleteVersion, renameVersion }] = useContext(ScheduleContext); @@ -26,8 +34,12 @@ export default function ComparisonContainer(): React.ReactElement { console.log('edit friend schedule'); }, []); - const handleRemoveSchedule = useCallback(() => { - console.log('remove friend schedule'); + const handleRemoveSchedule = useCallback((id: string) => { + console.log('remove friend schedule', id); + }, []); + + const handleRemoveFriend = useCallback((id: string) => { + console.log('remove user friend', id); }, []); const handleToggleSchedule = useCallback( @@ -83,27 +95,22 @@ export default function ComparisonContainer(): React.ReactElement {

My Schedules

{allVersionNames.map((version, i) => { return ( -
-
- {/* style={selected ? {background-color: {versionBgColor}} : {}} */} -

{version.name}

- - {allVersionNames.length >= 2 && ( - - )} -
+ handleToggleSchedule(version.id)} + checkboxColor={selected.includes(version.id) ? '#FFFFFF' : ''} + name={version.name} + // placeholder functions + handleEditSchedule={handleEditSchedule} + handleRemoveSchedule={(): void => { + setDeleteConfirm({ + id: version.id, + type: 'Version', + name: version.name, + }); + }} + hasDelete={allVersionNames.length >= 2} + /> ); })}
@@ -112,40 +119,40 @@ export default function ComparisonContainer(): React.ReactElement { {sharedSchedules.map((friend) => { return (
-

{friend.name}

+ { + setDeleteConfirm({ + id: friend.name, + type: 'User', + name: friend.name, + }); + }} + /> {friend.schedules.map((schedule, i) => { return ( -
-
- handleToggleSchedule(schedule.id) - } - style={ - selected.includes(schedule.id) - ? { backgroundColor: schedule.color } - : {} - } - /> - {/* style={selected ? {background-color: {versionBgColor}} : {}} */} -

{schedule.name}

- - {friend.schedules.length >= 2 && ( - - )} -
+ handleToggleSchedule(schedule.id)} + checkboxColor={ + selected.includes(schedule.id) ? schedule.color : '' + } + name={schedule.name} + handleEditSchedule={handleEditSchedule} + handleRemoveSchedule={(): void => { + setDeleteConfirm({ + id: schedule.id, + type: 'Schedule', + name: schedule.name, + owner: friend.name, + }); + }} + /> ); })}
@@ -162,8 +169,129 @@ export default function ComparisonContainer(): React.ReactElement { !compare && 'open' )} /> + setDeleteConfirm(null)} + buttons={[ + { + label: 'Cancel', + cancel: true, + onClick: (): void => setDeleteConfirm(null), + }, + { + label: 'Remove', + onClick: (): void => { + if (deleteConfirm != null) { + if (deleteConfirm.type === 'Version') { + deleteVersion(deleteConfirm.id); + } else if (deleteConfirm.type === 'User') { + handleRemoveFriend(deleteConfirm.id); + } else { + handleRemoveSchedule(deleteConfirm.id); + } + } + setDeleteConfirm(null); + }, + }, + ]} + preserveChildrenWhileHiding + > + {deleteConfirm?.type === 'Version' && ( +
+

Delete confirmation

+

+ Are you sure you want to delete schedule “ + {deleteConfirm?.name ?? ''}”? +

+
+ )} + {deleteConfirm?.type === 'User' && ( +
+

Remove User

+

+ Are you sure you want to remove the following user's + schedules from your view? +

+

+ User: {deleteConfirm?.name} +

+

+ You will not be able to see any of their schedules unless the + owner sends another invite for each one. +

+
+ )} + {deleteConfirm?.type === 'Schedule' && ( +
+

Remove Schedule

+

+ Are you sure you want to remove the following schedule from + your view? +

+

+ Schedule: {deleteConfirm?.name} +

+

+ Owner: {deleteConfirm?.owner} +

+

+ You will not be able to see it unless the owner sends another + invite. +

+
+ )} +
); } + +type ScheduleRowProps = { + id: string; + className?: string; + hasCheck?: boolean; + onClick?: () => void; + checkboxColor?: string; + name: string; + handleEditSchedule: () => void; + handleRemoveSchedule: () => void; + hasDelete?: boolean; +}; + +function ScheduleRow({ + id, + className, + hasCheck = true, + onClick, + checkboxColor, + name, + handleEditSchedule, + handleRemoveSchedule, + hasDelete = true, +}: ScheduleRowProps): React.ReactElement { + return ( +
+ {hasCheck && ( +
+ )} +

{name}

+ + {hasDelete && ( + + )} +
+ ); +} diff --git a/src/components/ComparisonContainer/stylesheet.scss b/src/components/ComparisonContainer/stylesheet.scss index 0db97d0e..1892cc00 100644 --- a/src/components/ComparisonContainer/stylesheet.scss +++ b/src/components/ComparisonContainer/stylesheet.scss @@ -6,12 +6,11 @@ flex-direction: column; border-bottom: 1px solid $color-border; white-space: nowrap; - padding: 12px; .comparison-header { display: flex; align-items: center; - margin-bottom: 7px; + margin: 11px 12px 7px 12px; p { margin: 0px; @@ -74,6 +73,8 @@ .comparison-content { position: relative; + margin-bottom: 12px; + p { margin: 0px; overflow: hidden; @@ -83,23 +84,21 @@ &.content-title{ font-weight: 700; - margin-top: 16px; - margin-bottom: 4px; + margin: 16px 12px 4px 12px; border-bottom: 1px solid $color-border; } } - .shared-schedules { - .checkbox-container { - padding-left: 12px; - } - } - .checkbox-container { display: flex; align-items: center; position: relative; height: 22px; + padding-left: 12px; + + &.indented { + padding-left: 24px; + } .checkbox { border: 1px solid; @@ -118,29 +117,21 @@ .icon { width: 27px; height: 100%; - position: relative; - right: -12px; padding: 0px; opacity: 0; } - &:hover .icon { - opacity: 1; + &:hover { + background-color: $color-border; + + & .icon { + opacity: 1; + } } p { flex: 1; } - - &:hover::after { - content: ''; - position: absolute; - left: -12px; - right: -12px; - height: 100%; - background-color: $color-border; - z-index: -10; - } } .comparison-overlay { @@ -148,8 +139,7 @@ pointer-events: none; opacity: 0; - z-index: 100; - transition-duration: 0.15s, $theme-switch-transition-duration; + transition-duration: 0.15s, $theme-switch-transition-duration, $theme-switch-transition-duration; transition-property: opacity, color, background-color; &.left { diff --git a/src/components/ComparisonPanel/index.tsx b/src/components/ComparisonPanel/index.tsx index 08e84d0f..74415033 100644 --- a/src/components/ComparisonPanel/index.tsx +++ b/src/components/ComparisonPanel/index.tsx @@ -1,4 +1,4 @@ -import React, { useState, useId } from 'react'; +import React, { useState, useId, useCallback } from 'react'; import { CombinationContainer, ComparisonContainer } from '..'; import { Tooltip as ReactTooltip } from 'react-tooltip'; import { classes } from '../../utils/misc'; @@ -7,8 +7,17 @@ import './stylesheet.scss'; export default function ComparisonPanel(): React.ReactElement { const [expanded, setExpanded] = useState(true); const [hover, setHover] = useState(false); + const [tooltipY, setTooltipY] = useState(0); const tooltipId = useId(); + const handleHover = useCallback( + (e: React.MouseEvent) => { + setHover(true); + setTooltipY(e.clientY); + }, + [hover, tooltipY] + ); + return (
setHover(true)} + onMouseEnter={(e: React.MouseEvent): void => { + handleHover(e); + }} onMouseLeave={(): void => setHover(false)} id={tooltipId} > @@ -27,15 +38,15 @@ export default function ComparisonPanel(): React.ReactElement {