Skip to content

Commit

Permalink
support for archive and fix responsiveness issues
Browse files Browse the repository at this point in the history
  • Loading branch information
rithviknishad committed Oct 26, 2023
1 parent fb19237 commit ab9aa6e
Show file tree
Hide file tree
Showing 10 changed files with 666 additions and 203 deletions.
13 changes: 8 additions & 5 deletions src/CAREUI/display/RecordMeta.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import CareIcon from "../icons/CareIcon";
import { formatDateTime, isUserOnline, relativeTime } from "../../Utils/utils";
import {
formatDateTime,
formatName,
isUserOnline,
relativeTime,
} from "../../Utils/utils";
import { ReactNode } from "react";

interface Props {
Expand Down Expand Up @@ -30,7 +35,7 @@ const RecordMeta = ({ time, user, prefix, className, inlineUser }: Props) => {
<span className="flex items-center gap-1">
by
<CareIcon className="care-l-user" />
{user.first_name} {user.last_name}
{formatName(user)}
{isOnline && (
<div className="h-1.5 w-1.5 rounded-full bg-primary-400" />
)}
Expand All @@ -48,9 +53,7 @@ const RecordMeta = ({ time, user, prefix, className, inlineUser }: Props) => {
{user && inlineUser && <span>by</span>}
{user && <CareIcon className="care-l-user" />}
{user && inlineUser && (
<span className="font-medium">
{user.first_name} {user.last_name}
</span>
<span className="font-medium">{formatName(user)}</span>
)}
</div>
);
Expand Down
157 changes: 157 additions & 0 deletions src/CAREUI/display/Timeline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import { createContext, useContext } from "react";
import { PerformedByModel } from "../../Components/HCX/misc";
import { classNames, formatName } from "../../Utils/utils";
import CareIcon, { IconName } from "../icons/CareIcon";
import RecordMeta from "./RecordMeta";

export interface TimelineEvent<TType = string> {
type: TType;
timestamp: string;
by: PerformedByModel | undefined;
icon: IconName;
notes?: string;
cancelled?: boolean;
}

interface TimelineProps {
className: string;
children: React.ReactNode | React.ReactNode[];
name: string;
}

const TimelineContext = createContext("");

export default function Timeline({ className, children, name }: TimelineProps) {
return (
<div className={className}>
<ol role="list" className="space-y-6">
<TimelineContext.Provider value={name}>
{children}
</TimelineContext.Provider>
</ol>
</div>
);
}

interface TimelineNodeProps {
event: TimelineEvent;
title?: React.ReactNode;
/**
* Used to add a suffix to the auto-generated title. Will be ignored if `title` is provided.
*/
titleSuffix?: React.ReactNode;
actions?: React.ReactNode;
className?: string;
children?: React.ReactNode;
name?: string;
isLast: boolean;
}

export const TimelineNode = (props: TimelineNodeProps) => {
const name = useContext(TimelineContext);

return (
<li className="relative flex gap-x-4">
<div
className={classNames(
props.isLast ? "h-6" : "-bottom-6",
"absolute left-0 top-0 flex w-6 justify-center"
)}
>
<div className="w-px bg-gray-300" />
</div>

<div
className={classNames(
props.className,
"flex w-full flex-col items-start gap-y-1"
)}
>
<div className="relative flex w-full justify-between gap-x-4">
<div
className={classNames(
"flex w-full gap-x-4",
props.event.cancelled && "line-through"
)}
>
{props.title || (
<TimelineNodeTitle event={props.event}>
<p className="flex-auto py-0.5 text-xs leading-5 text-gray-600">
{props.event.by && (
<span className="font-medium text-gray-900">
{formatName(props.event.by)}{" "}
</span>
)}
{props.titleSuffix
? props.titleSuffix
: `${props.event.type} the ${props.name || name}.`}
</p>
<RecordMeta
className="flex-none py-0.5 text-xs leading-5 text-gray-500"
time={props.event.timestamp}
/>
</TimelineNodeTitle>
)}
</div>

{props.actions && (
<TimelineNodeActions>{props.actions}</TimelineNodeActions>
)}
</div>

<div className="flex w-full flex-col items-start gap-y-2 pl-10">
<TimelineNodeNotes>{props.event.notes}</TimelineNodeNotes>
{props.children}
</div>
</div>
</li>
);
};

interface TimelineNodeTitleProps {
children: React.ReactNode | React.ReactNode[];
event: TimelineEvent;
}

export const TimelineNodeTitle = (props: TimelineNodeTitleProps) => {
return (
<>
<div className="relative flex h-6 w-6 flex-none items-center justify-center bg-gray-200 transition-all duration-200 ease-in-out group-hover:bg-primary-500">
<CareIcon
className="text-lg text-gray-700 transition-all duration-200 ease-in-out group-hover:text-white"
aria-hidden="true"
icon={props.event.icon}
/>
</div>

<div className="flex w-full justify-between">{props.children}</div>
</>
);
};

export const TimelineNodeActions = (props: {
children: React.ReactNode | React.ReactNode[];
}) => {
return <div className="flex justify-end gap-2">{props.children}</div>;
};

interface TimelineNodeNotesProps {
children?: React.ReactNode | React.ReactNode[];
icon?: IconName;
}

export const TimelineNodeNotes = ({
children,
icon = "l-notes",
}: TimelineNodeNotesProps) => {
if (!children) {
return;
}

return (
<div className="flex w-full items-start gap-2 rounded-md p-3 ring-1 ring-inset ring-gray-200">
<CareIcon icon={icon} className="text-lg text-gray-700" />
<div className="mt-1 flex-auto text-xs text-gray-700">{children}</div>
</div>
);
};
Loading

0 comments on commit ab9aa6e

Please sign in to comment.