Skip to content

Commit

Permalink
Merge pull request #243 from Lemoncode/feature/#159-Add-Calendar-Comp…
Browse files Browse the repository at this point in the history
…onent

Feature/#159 add calendar component
  • Loading branch information
brauliodiez authored Aug 22, 2024
2 parents 06b539e + 6535c29 commit 0cfe042
Show file tree
Hide file tree
Showing 11 changed files with 308 additions and 0 deletions.
68 changes: 68 additions & 0 deletions public/rich-components/calendar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// TODO: #250 Add Unit tests
// https://github.com/Lemoncode/quickmock/issues/250

export const calculatePreviousMonth = (date: Date) =>
new Date(date.getFullYear(), date.getMonth() - 1, 1);

export const calculateNextMonth = (date: Date) =>
new Date(date.getFullYear(), date.getMonth() + 1, 1);

export const getCurrentMonthDays = (date: Date) => {
const month = date.toLocaleString('en', { month: 'long' });
const year = date.getFullYear();
const daysInMonth = new Date(year, date.getMonth() + 1, 0).getDate();
const startDay = new Date(year, date.getMonth(), 1).getDay();

const days = [];
let week = new Array(startDay).fill(null); // Fill the first week with nulls up to the start day

for (let day = 1; day <= daysInMonth; day++) {
week.push(day);
if (week.length === 7 || day === daysInMonth) {
days.push(week);
week = [];
}
}

return { month, year, days };
};
166 changes: 166 additions & 0 deletions src/common/components/front-rich-components/calendar/calendar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import { useState, forwardRef } from 'react';
import { Group, Rect, Text, Line } from 'react-konva';
import { ShapeSizeRestrictions } from '@/core/model';
import { ShapeProps } from '../../front-components/shape.model';
import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions';
import {
calculateNextMonth,
calculatePreviousMonth,
getCurrentMonthDays,
} from './calendar.business';

const calendarShapeSizeRestrictions: ShapeSizeRestrictions = {
minWidth: 350,
minHeight: 350,
maxWidth: -1,
maxHeight: -1,
defaultWidth: 500,
defaultHeight: 500,
};

export const getCalendarShapeSizeRestrictions = (): ShapeSizeRestrictions =>
calendarShapeSizeRestrictions;

export const CalendarShape = forwardRef<any, ShapeProps>(
({ x, y, width, height, id, onSelected, ...shapeProps }, ref) => {
const { width: restrictedWidth, height: restrictedHeight } =
fitSizeToShapeSizeRestrictions(
calendarShapeSizeRestrictions,
width,
height
);

const [currentDate, setCurrentDate] = useState(new Date());

const handlePrevMonth = () => {
setCurrentDate(prevDate => calculatePreviousMonth(prevDate));
};

const handleNextMonth = () => {
setCurrentDate(prevDate => calculateNextMonth(prevDate));
};

const { month, year, days } = getCurrentMonthDays(currentDate);

const margin = 10;
const headerHeight = 50;
const dayBoxWidth = (restrictedWidth - margin * 2) / 7;
const dayBoxHeight = (height - headerHeight) / days.length;

return (
<Group
x={x}
y={y}
ref={ref}
width={restrictedWidth}
height={restrictedHeight}
{...shapeProps}
onClick={() => onSelected(id, 'calendar')}
>
{/* Encabezado del calendario */}
<Rect
x={0}
y={0}
width={restrictedWidth}
height={headerHeight}
cornerRadius={10}
stroke="black"
strokeWidth={2}
fill="white"
/>

{/* Left arrow */}
<Line
points={[
margin + 20,
margin + 10,
margin + 10,
margin + 20,
margin + 20,
margin + 30,
]}
closed
fill="black"
stroke="black"
strokeWidth={2}
onClick={handlePrevMonth}
cursor="pointer"
/>

{/* Year and month */}

<Text
x={margin + 20}
y={headerHeight / 3}
text={`${month} ${year}`}
width={restrictedWidth - margin - 20 - margin - 30}
fontFamily="Comic Sans MS, cursive"
fontSize={20}
fill="black"
align="center"
ellipsis={true}
/>

{/* Right arrow */}
<Line
points={[
restrictedWidth - margin - 30,
margin + 10,
restrictedWidth - margin - 20,
margin + 20,
restrictedWidth - margin - 30,
margin + 30,
]}
closed
fill="black"
stroke="black"
strokeWidth={2}
onClick={handleNextMonth}
cursor="pointer"
/>

{/* Calendar table */}
<Rect
x={0}
y={headerHeight + 10}
width={restrictedWidth}
height={height - headerHeight + 20}
cornerRadius={10}
stroke="black"
strokeWidth={2}
fill="white"
/>

{/* Week days */}
{['S', 'M', 'T', 'W', 'T', 'F', 'S'].map((day, i) => (
<Text
key={i}
x={35 + i * dayBoxWidth}
y={headerHeight + 20}
text={day}
fontFamily="Comic Sans MS, cursive"
fontSize={16}
fill="black"
/>
))}

{/* Month days */}
{days.map((week: any[], rowIndex: number) =>
week.map((day, colIndex) => (
<Text
key={`${rowIndex}-${colIndex}`}
x={35 + colIndex * dayBoxWidth}
y={headerHeight + 70 + rowIndex * dayBoxHeight}
text={day ? day.toString() : ''}
fontFamily="Comic Sans MS, cursive"
fontSize={16}
fill="black"
/>
))
)}
</Group>
);
}
);

export default CalendarShape;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './calendar';
1 change: 1 addition & 0 deletions src/common/components/front-rich-components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export * from './map-chart';
export * from './video-player';
export * from './bar-chart';
export * from './line-chart';
export * from './calendar/calendar';
export * from './table/table';
3 changes: 3 additions & 0 deletions src/core/model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ export type ShapeType =
| 'largeArrow'
| 'bar'
| 'triangle'
| 'horizontalScrollBar'
| 'image'
| 'calendar'
| 'image'
| 'table'
| 'verticalScrollBar'
Expand Down Expand Up @@ -95,6 +97,7 @@ export const ShapeDisplayName: Record<ShapeType, string> = {
image: 'Image',
table: 'Table',
horizontalScrollBar: 'Horizontal Scroll Bar',
calendar: 'Calendar',
verticalScrollBar: 'Vertical Scroll Bar',
};

Expand Down
6 changes: 6 additions & 0 deletions src/pods/canvas/canvas.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
getHorizontalMenuShapeSizeRestrictions,
getMapChartShapeSizeRestrictions,
getLineChartShapeSizeRestrictions,
getCalendarShapeSizeRestrictions,
getTableSizeRestrictions,
} from '@/common/components/front-rich-components';
import {
Expand Down Expand Up @@ -269,6 +270,11 @@ export const getDefaultSizeFromShape = (shapeType: ShapeType): Size => {
width: getHorizontalScrollBarShapeSizeRestrictions().defaultWidth,
height: getHorizontalScrollBarShapeSizeRestrictions().defaultHeight,
};
case 'calendar':
return {
width: getCalendarShapeSizeRestrictions().defaultWidth,
height: getCalendarShapeSizeRestrictions().defaultHeight,
};
case 'verticalScrollBar':
return {
width: getVerticalScrollBarShapeSizeRestrictions().defaultWidth,
Expand Down
3 changes: 3 additions & 0 deletions src/pods/canvas/shape-renderer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
import { renderSmalltext } from './simple-text-components/smalltext.renderer';
import { renderParagraph } from './simple-text-components/paragraph.renderer';
import { renderImage } from './simple-basic-shapes/image.renderer';
import { renderCalendar } from './simple-rich-components/calendar.renderer';

export const renderShapeComponent = (
shape: ShapeModel,
Expand Down Expand Up @@ -99,6 +100,8 @@ export const renderShapeComponent = (
return renderPieChart(shape, shapeRenderedProps);
case 'map':
return renderMapChart(shape, shapeRenderedProps);
case 'calendar':
return renderCalendar(shape, shapeRenderedProps);
case 'linechart':
return renderLineChart(shape, shapeRenderedProps);
case 'diamond':
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { CalendarShape } from '@/common/components/front-rich-components/calendar';
import { ShapeRendererProps } from '../model';
import { ShapeModel } from '@/core/model';

export const renderCalendar = (
shape: ShapeModel,
shapeRenderedProps: ShapeRendererProps
) => {
const { handleSelected, shapeRefs, handleDragEnd, handleTransform } =
shapeRenderedProps;

return (
<CalendarShape
id={shape.id}
key={shape.id}
ref={shapeRefs.current[shape.id]}
x={shape.x}
y={shape.y}
name="shape"
width={shape.width}
height={shape.height}
draggable
typeOfTransformer={shape.typeOfTransformer}
onSelected={handleSelected}
onDragEnd={handleDragEnd(shape.id)}
onTransform={handleTransform}
onTransformEnd={handleTransform}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export * from './map-chart.renderer';
export * from './breadcrumb.renderer';
export * from './bar-chart.renderer';
export * from './line-chart.renderer';
export * from './calendar.renderer';
export * from './table.renderer';
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ export const mockRichComponentsCollection: ItemInfo[] = [
{ thumbnailSrc: '/rich-components/map.svg', type: 'map' },
{ thumbnailSrc: '/rich-components/barchart.svg', type: 'bar' },
{ thumbnailSrc: '/rich-components/line-chart.svg', type: 'linechart' },
{ thumbnailSrc: '/rich-components/calendar.svg', type: 'calendar' },
{ thumbnailSrc: '/rich-components/table.svg', type: 'table' },
];

0 comments on commit 0cfe042

Please sign in to comment.