Skip to content

Commit

Permalink
timeline
Browse files Browse the repository at this point in the history
  • Loading branch information
ijavad805 committed Jun 3, 2024
1 parent 6faf9e6 commit 9375c64
Show file tree
Hide file tree
Showing 49 changed files with 775 additions and 92 deletions.
14 changes: 9 additions & 5 deletions packages/core/src/components/bear-calendar/style.scss
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
.bear-calendar {
font-family: Arial, sans-serif;
height: 100%;

* {
--primary: #3788d8;
--primary-container: #2f71b3;
--secondary: rgb(216, 146, 16);
--secondary-container: rgb(173, 117, 13);
--surface: #fff;
--text: rgb(61, 61, 61);
--surface-2: #e0e0e0;
--text: rgb(3, 0, 0);
--text-hover: #141414;
--border-color: rgba(0, 0, 0, 0.125);
--disable-day-color: #f0f0f0;
--past-date-dots: #f5ffd0;
--space-sm: 2px;
--space-md: 5px;
--space-lg: 10px;
--space-tn: 2px;
--space-sm: 4px;
--space-md: 8px;
--space-lg: 16px;
--secondary-color: #818181;
--corner: 5px;
--hover: rgba(0, 0, 0, 0.125);
}
}
}
44 changes: 44 additions & 0 deletions packages/core/src/components/bear-calendar/view/footer/footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import classes from "./style.module.scss";
import {
joinClass,
PluginName,
useCalendarProps,
View,
} from "@bear-calendar/utility";
import React, {useMemo, useState} from "react";

interface IProps {
children: React.ReactNode;
activePlugin: keyof typeof PluginName;
changeView: (name: keyof typeof PluginName) => void;
}

export const Footer: React.FC<IProps> = ({
children,
changeView,
activePlugin,
}) => {
const props = useCalendarProps();

return (
<View className={classes.footer} horizontal spaceBetween center>
{props.plugin.length > 1 && (
<View space="tiny" horizontal>
{props.plugin.map((item) => (
<View
center
className={joinClass(classes.plugin, [
activePlugin === item.name,
classes.active,
])}
onClick={changeView.bind(window, item.name)}
>
{item.name.split("")[0]}
</View>
))}
</View>
)}
{children}
</View>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./footer";
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.footer {
background: var(--primary);
padding: var(--space-tn);
color: var(--surface);

.plugin {
width: 20px;
height: 20px;
&.active {
}
}

&:empty {
display: none;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.view {
height: 100%;
.body {
height: 100%;
border: 1px solid var(--border-color);
border-bottom: unset;
}
}
19 changes: 19 additions & 0 deletions packages/core/src/components/bear-calendar/view/view.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {PluginName, useCalendarProps} from "@bear-calendar/utility";
import React, {useEffect, useMemo, useState} from "react";
import classes from "./style.module.scss";
import {Footer} from "./footer";
export const View: React.FC = () => {
const calendarProps = useCalendarProps();
const [activeView, setActiveView] = useState<keyof typeof PluginName>(
Expand All @@ -18,6 +19,18 @@ export const View: React.FC = () => {
return <>View Not Found</>;
}, [activeView]);

const footer = useMemo(() => {
if (activeView) {
const findView = calendarProps.plugin.find(
(i) => i.name === activeView
);

if (findView && findView.footer) return findView.footer();
}

return null;
}, [activeView]);

useEffect(() => {
if (calendarProps.view) setActiveView(calendarProps.view);
}, [calendarProps.view]);
Expand All @@ -41,6 +54,12 @@ export const View: React.FC = () => {
)}

<div className={classes.body}>{view}</div>
<Footer
changeView={(name) => setActiveView(name)}
activePlugin={activeView}
>
{footer}
</Footer>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
display: flex;
justify-content: space-between;
align-items: center;
border: 1px solid var(--border-color);
border-bottom: unset;
background-color: var(--surface);
height: 30px;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
z-index: 1;
box-sizing: content-box;
min-height: 100%;
padding: var(--space-sm);
padding: var(--space-tn);

.header {
display: flex;
Expand All @@ -11,7 +11,7 @@
font-size: 12px;
-webkit-user-select: none;
user-select: none;
padding: var(--space-md);
padding: var(--space-sm);
}

.events {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
display: flex;
align-items: center;
font-size: 10px;
padding: var(--space-md);
padding: var(--space-sm);
border-radius: 3px;
background: var(--primary);
-webkit-user-select: none;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import React, {useMemo} from "react";
import {IEventModel, useCalendarProps, View} from "@bear-calendar/utility";
import {useTimelineProps} from "../../../timeline/useTimelineProps";
import dayjs from "dayjs";
import classes from "./style.module.scss";
import {EventHolder} from "./eventHolder";

type IWithPriority = {
priority: number;
event: IEventModel;
};
interface IProps {
events: IEventModel[];
}
export const EventHandler: React.FC<IProps> = (props) => {
const timelineProps = useTimelineProps();
const [maxPriority, withPriority] = useMemo(() => {
const maxPriority = 0;
const withPriority: IWithPriority[] = [];

const isThereConflict = (
current: dayjs.Dayjs,
start: string,
end: string
) => {
return current.isAfter(start) && current.isBefore(end);
};

const startFrom =
(timelineProps.maxEventPerGroup || 0) > props.events.length
? props.events.length
: timelineProps.maxEventPerGroup;

for (let i = startFrom === undefined ? 5 : startFrom; i >= 0; --i) {
const event = props.events[i];

let priority = 0;
if (event) {
for (let j = withPriority.length; j >= 0; j--) {
const prevEvent = withPriority[j];
if (prevEvent) {
if (
isThereConflict(
dayjs(event.date.start),
prevEvent.event.date.start,
prevEvent.event.date.end
) ||
isThereConflict(
dayjs(event.date.start),
prevEvent.event.date.start,
prevEvent.event.date.end
)
) {
priority =
priority < prevEvent.priority
? prevEvent.priority + 1
: priority;
}
}
}
withPriority.push({
priority,
event,
});
}
}
return [maxPriority, withPriority];
}, [props.events]);

const [differentIn] = useMemo(() => {
let format: Parameters<typeof EventHolder>["0"]["differentIn"];
switch (timelineProps.zoomLevel) {
case "month":
format = "days";
break;
case "day":
format = "hours";
break;
case "week":
format = "days";
break;
}

return [format];
}, [timelineProps.zoomLevel]);

const render = () => {
const events = [];
for (let i = maxPriority; i >= 0; i--) {
events.push(
<View className={classes.line} space="tiny">
{withPriority
.filter((e) => e.priority === i)
.map((event) => (
<EventHolder
differentIn={differentIn}
event={event.event}
/>
))}
</View>
);
}

return events;
};

return <View>{render().map((i) => i)}</View>;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {EventCard, IEventModel, View} from "@bear-calendar/utility";
import dayjs from "dayjs";
import React from "react";
import classes from "./style.module.scss";
import {useTimelineProps} from "../../../timeline/useTimelineProps";
import {useEventHolder} from "./useEventHolder";

export interface IEventHolderProps {
differentIn: Parameters<dayjs.Dayjs["diff"]>["1"];
event: IEventModel;
}
export const EventHolder: React.FC<IEventHolderProps> = (props) => {
const propsTimeline = useTimelineProps();
const {left, width} = useEventHolder(props);

return (
<View
className={classes.event}
style={{left: `${left}px`, width: `${width}px`}}
>
{propsTimeline.renderEvent ? (
propsTimeline.renderEvent(props.event)
) : (
<EventCard event={props.event} />
)}
</View>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./eventHandler";
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.line {
.title {
display: flex;
align-items: center;
}


}

.event {
position: relative;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {IEventModel, useStore} from "@bear-calendar/utility";
import {useMemo} from "react";
import {IEventHolderProps} from "./eventHolder";
import dayjs from "dayjs";
import {useTimelineProps} from "../../../timeline/useTimelineProps";

export const useEventHolder = (props: IEventHolderProps) => {
const propsTimeline = useTimelineProps();
const {current} = useStore();
const [left, width] = useMemo(() => {
let left = 0;
let width;
const cellWidth = 80; // TODO :: should be sync width header items

const diff = dayjs(props.event.date.end).diff(
props.event.date.start,
props.differentIn
);
width = (diff || 1) * cellWidth;

left = Math.abs(
current
.startOf(propsTimeline.zoomLevel)
.diff(props.event.date.start, props.differentIn) * cellWidth
);

return [left, width];
}, []);

return {left, width};
};
Loading

0 comments on commit 9375c64

Please sign in to comment.