akfatimeline 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +924 -0
- package/babel.config.json +4 -0
- package/package.json +50 -0
- package/public/favicon.ico +0 -0
- package/public/index.html +43 -0
- package/public/logo192.png +0 -0
- package/public/logo512.png +0 -0
- package/public/manifest.json +25 -0
- package/public/robots.txt +3 -0
- package/src/App copy.js +185 -0
- package/src/App.css +38 -0
- package/src/App.js +201 -0
- package/src/App.test.js +8 -0
- package/src/components/Timeline/DragAndDropHandler.js +35 -0
- package/src/components/Timeline/EventTooltip.js +206 -0
- package/src/components/Timeline/Indicator.js +30 -0
- package/src/components/Timeline/MasterHeader.js +55 -0
- package/src/components/Timeline/Resources.js +53 -0
- package/src/components/Timeline/ResourcesHeader.js +14 -0
- package/src/components/Timeline/Timeline.css +534 -0
- package/src/components/Timeline/Timeline.js +277 -0
- package/src/components/Timeline/TimelineCell.js +8 -0
- package/src/components/Timeline/TimelineContent copy.js +421 -0
- package/src/components/Timeline/TimelineContent.js +422 -0
- package/src/components/Timeline/TimelineEvents.js +114 -0
- package/src/components/Timeline/TimelineHeader.js +43 -0
- package/src/components/Timeline/TimelineMonthContainer.js +29 -0
- package/src/components/Timeline/TimelineResources.js +16 -0
- package/src/dist/Timeline.js +277 -0
- package/src/hooks/useDragAndDrop.js +80 -0
- package/src/hooks/useEventDragDrop.js +120 -0
- package/src/hooks/useExtendEvent.js +28 -0
- package/src/index.css +13 -0
- package/src/index.js +17 -0
- package/src/logo.svg +1 -0
- package/src/reportWebVitals.js +13 -0
- package/src/setupTests.js +5 -0
- package/src/utils/HorizontalVirtualScroll.js +0 -0
- package/src/utils/dateUtils.js +36 -0
- package/src/utils/filterTimelineData.js +21 -0
- package/src/utils/timelineUtils.js +40 -0
- package/webpack.config.js +31 -0
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "akfatimeline",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A customizable timeline component for React applications",
|
|
5
|
+
"main": "dist/Timeline.js",
|
|
6
|
+
"module": "dist/Timeline.js",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"cra-template": "1.2.0",
|
|
9
|
+
"react": "^19.0.0",
|
|
10
|
+
"react-dom": "^19.0.0",
|
|
11
|
+
"react-scripts": "5.0.1",
|
|
12
|
+
"react-window": "^1.8.11",
|
|
13
|
+
"uuid": "^11.0.3",
|
|
14
|
+
"web-vitals": "^4.2.4"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"start": "react-scripts start",
|
|
18
|
+
"build": "react-scripts build",
|
|
19
|
+
"test": "react-scripts test",
|
|
20
|
+
"eject": "react-scripts eject"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"timeline",
|
|
24
|
+
"react",
|
|
25
|
+
"schedule",
|
|
26
|
+
"akfa",
|
|
27
|
+
"Akfasoft",
|
|
28
|
+
"akfatimeline",
|
|
29
|
+
"Akfasoft yazılım"
|
|
30
|
+
],
|
|
31
|
+
"author": "Ahmet Kürşad Aydoğan",
|
|
32
|
+
"eslintConfig": {
|
|
33
|
+
"extends": [
|
|
34
|
+
"react-app",
|
|
35
|
+
"react-app/jest"
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
"browserslist": {
|
|
39
|
+
"production": [
|
|
40
|
+
">0.2%",
|
|
41
|
+
"not dead",
|
|
42
|
+
"not op_mini all"
|
|
43
|
+
],
|
|
44
|
+
"development": [
|
|
45
|
+
"last 1 chrome version",
|
|
46
|
+
"last 1 firefox version",
|
|
47
|
+
"last 1 safari version"
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
+
<meta name="theme-color" content="#000000" />
|
|
8
|
+
<meta
|
|
9
|
+
name="description"
|
|
10
|
+
content="Web site created using create-react-app"
|
|
11
|
+
/>
|
|
12
|
+
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
|
13
|
+
<!--
|
|
14
|
+
manifest.json provides metadata used when your web app is installed on a
|
|
15
|
+
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
|
16
|
+
-->
|
|
17
|
+
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
|
18
|
+
<!--
|
|
19
|
+
Notice the use of %PUBLIC_URL% in the tags above.
|
|
20
|
+
It will be replaced with the URL of the `public` folder during the build.
|
|
21
|
+
Only files inside the `public` folder can be referenced from the HTML.
|
|
22
|
+
|
|
23
|
+
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
|
24
|
+
work correctly both with client-side routing and a non-root public URL.
|
|
25
|
+
Learn how to configure a non-root public URL by running `npm run build`.
|
|
26
|
+
-->
|
|
27
|
+
<title>React App</title>
|
|
28
|
+
</head>
|
|
29
|
+
<body>
|
|
30
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
31
|
+
<div id="root"></div>
|
|
32
|
+
<!--
|
|
33
|
+
This HTML file is a template.
|
|
34
|
+
If you open it directly in the browser, you will see an empty page.
|
|
35
|
+
|
|
36
|
+
You can add webfonts, meta tags, or analytics to this file.
|
|
37
|
+
The build step will place the bundled scripts into the <body> tag.
|
|
38
|
+
|
|
39
|
+
To begin the development, run `npm start` or `yarn start`.
|
|
40
|
+
To create a production bundle, use `npm run build` or `yarn build`.
|
|
41
|
+
-->
|
|
42
|
+
</body>
|
|
43
|
+
</html>
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"short_name": "React App",
|
|
3
|
+
"name": "Create React App Sample",
|
|
4
|
+
"icons": [
|
|
5
|
+
{
|
|
6
|
+
"src": "favicon.ico",
|
|
7
|
+
"sizes": "64x64 32x32 24x24 16x16",
|
|
8
|
+
"type": "image/x-icon"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"src": "logo192.png",
|
|
12
|
+
"type": "image/png",
|
|
13
|
+
"sizes": "192x192"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"src": "logo512.png",
|
|
17
|
+
"type": "image/png",
|
|
18
|
+
"sizes": "512x512"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"start_url": ".",
|
|
22
|
+
"display": "standalone",
|
|
23
|
+
"theme_color": "#000000",
|
|
24
|
+
"background_color": "#ffffff"
|
|
25
|
+
}
|
package/src/App copy.js
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import Timeline from "./components/Timeline/Timeline";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const App = () => {
|
|
6
|
+
const programDate = "2025-01-02";
|
|
7
|
+
const [dropInfo, setDropInfo] = useState(null);
|
|
8
|
+
|
|
9
|
+
const events = [
|
|
10
|
+
{
|
|
11
|
+
id: "lux-101-1",
|
|
12
|
+
title: "Room 101 Event",
|
|
13
|
+
startDate: new Date("2025-01-01"), // Giriş tarihi
|
|
14
|
+
endDate: new Date("2025-01-08"), // Çıkış tarihi
|
|
15
|
+
resourceId: "lux-101", // Kaynak ID
|
|
16
|
+
color: "#ff5733", // Renk
|
|
17
|
+
totalAmount: 500, // Toplam borç
|
|
18
|
+
amountPaid: 200, // Ödenen miktar
|
|
19
|
+
status: "Confirmed", // Rezervasyon durumu
|
|
20
|
+
note: "Misafirler özel talep olarak ekstra yastık istediler." // Rezervasyon notu
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: "lux-102-1",
|
|
24
|
+
title: "Room 102 Event",
|
|
25
|
+
startDate: new Date("2025-01-02"),
|
|
26
|
+
endDate: new Date("2025-01-04"),
|
|
27
|
+
resourceId: "lux-102",
|
|
28
|
+
color: "#33a1ff",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "lux-103-1",
|
|
32
|
+
title: "Room 103 Event",
|
|
33
|
+
startDate: new Date("2025-01-01"),
|
|
34
|
+
endDate: new Date("2025-01-02"),
|
|
35
|
+
resourceId: "lux-103",
|
|
36
|
+
color: "#33ff57",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "fam-201-1",
|
|
40
|
+
title: "Suite 201 Event",
|
|
41
|
+
startDate: new Date("2025-01-01"),
|
|
42
|
+
endDate: new Date("2025-01-02"),
|
|
43
|
+
resourceId: "fam-201",
|
|
44
|
+
color: "#ff33a1",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: "fam-202-1",
|
|
48
|
+
title: "Suite 202 Event",
|
|
49
|
+
startDate: new Date("2025-01-03"),
|
|
50
|
+
endDate: new Date("2025-01-05"),
|
|
51
|
+
resourceId: "fam-202",
|
|
52
|
+
color: "#a1ff33",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: "bus-301-1",
|
|
56
|
+
title: "Room 301 Event",
|
|
57
|
+
startDate: new Date("2025-01-02"),
|
|
58
|
+
endDate: new Date("2025-01-04"),
|
|
59
|
+
resourceId: "bus-301",
|
|
60
|
+
color: "#ff9a00",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: "vip-401-1",
|
|
64
|
+
title: "VIP 401 Event",
|
|
65
|
+
startDate: new Date("2025-01-04"),
|
|
66
|
+
endDate: new Date("2025-01-06"),
|
|
67
|
+
resourceId: "vip-401",
|
|
68
|
+
color: "#800080",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: "vip-402-1",
|
|
72
|
+
title: "VIP 402 Event",
|
|
73
|
+
startDate: new Date("2025-01-05"),
|
|
74
|
+
endDate: new Date("2025-01-06"),
|
|
75
|
+
resourceId: "vip-402",
|
|
76
|
+
color: "#008080",
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
const resources = [
|
|
81
|
+
{
|
|
82
|
+
groupName: "Luxury Rooms",
|
|
83
|
+
resources: [
|
|
84
|
+
{ id: "lux-101", name: "Room 101" },
|
|
85
|
+
{ id: "lux-102", name: "Room 102" },
|
|
86
|
+
{ id: "lux-103", name: "Room 103" },
|
|
87
|
+
{ id: "lux-104", name: "Room 104" },
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
groupName: "Family Suites",
|
|
92
|
+
resources: [
|
|
93
|
+
{ id: "fam-201", name: "Suite 201" },
|
|
94
|
+
{ id: "fam-202", name: "Suite 202" },
|
|
95
|
+
{ id: "fam-203", name: "Suite 203" },
|
|
96
|
+
{ id: "fam-204", name: "Suite 204" },
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
groupName: "Business Class",
|
|
101
|
+
resources: [
|
|
102
|
+
{ id: "bus-301", name: "Room 301" },
|
|
103
|
+
{ id: "bus-302", name: "Room 302" },
|
|
104
|
+
{ id: "bus-303", name: "Room 303" },
|
|
105
|
+
{ id: "bus-304", name: "Room 304" },
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
groupName: "VIP Exclusive",
|
|
110
|
+
resources: [
|
|
111
|
+
{ id: "vip-401", name: "VIP 401" },
|
|
112
|
+
{ id: "vip-402", name: "VIP 402" },
|
|
113
|
+
{ id: "vip-403", name: "VIP 403" },
|
|
114
|
+
{ id: "vip-404", name: "VIP 404" },
|
|
115
|
+
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
const resourceSettings = {
|
|
121
|
+
showIdAsName: false,
|
|
122
|
+
isGrouped: true,
|
|
123
|
+
isCollapsible: true,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// Yeni prop'lar (boolean veya callback) örnekleri:
|
|
127
|
+
const eventsDragOn = true; // Etkinlikleri sürükle-bırak aktif mi?
|
|
128
|
+
const eventsExtendOn = true; // Etkinliği sağ kenarından uzatma aktif mi?
|
|
129
|
+
const createNewEventOn = true; // Yeni event oluşturma aktif mi?
|
|
130
|
+
// Callback örnekleri:
|
|
131
|
+
const handleDragInfo = (dragData) => {
|
|
132
|
+
console.log("Dragged Event Info:", dragData);
|
|
133
|
+
// Kullanıcı bu veriyi yakalayıp kendi API'sine kaydedebilir
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const [masterHeaderView, setMasterHeaderView] = useState(true);
|
|
137
|
+
const [resourceHeaderContent, setResourceHeaderContent] = useState("Akfa Timeline");
|
|
138
|
+
|
|
139
|
+
const handleExtendInfo = (extendData) => {
|
|
140
|
+
console.log("Extended Event Info:", extendData);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const handleCreateEventInfo = (newEventData) => {
|
|
144
|
+
console.log("New Event Created:", newEventData);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const handleEventClick = (evt, ev) => {
|
|
148
|
+
console.log("Event clicked:", evt);
|
|
149
|
+
// evt: event objesi, ev: orijinal mouse event
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const handleEventRightClick = (evt, ev) => {
|
|
153
|
+
ev.preventDefault(); // Sağ tık menüsü kapatmak istersen
|
|
154
|
+
console.log("Event right-clicked:", evt);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<Timeline
|
|
159
|
+
resources={resources}
|
|
160
|
+
resourceSettings={resourceSettings}
|
|
161
|
+
programDate={programDate}
|
|
162
|
+
externalEvents={events}
|
|
163
|
+
indicatorOn={true}
|
|
164
|
+
events={events}
|
|
165
|
+
setDropInfo={setDropInfo}
|
|
166
|
+
|
|
167
|
+
eventsDragOn={eventsDragOn}
|
|
168
|
+
eventsExtendOn={eventsExtendOn}
|
|
169
|
+
createNewEventOn={createNewEventOn}
|
|
170
|
+
|
|
171
|
+
onDragInfo={handleDragInfo}
|
|
172
|
+
onExtendInfo={handleExtendInfo}
|
|
173
|
+
onCreateEventInfo={handleCreateEventInfo}
|
|
174
|
+
onEventClick={handleEventClick}
|
|
175
|
+
onEventRightClick={handleEventRightClick}
|
|
176
|
+
|
|
177
|
+
horizontalScrollOn={true} // => Yatay kaydırma aktifleştirilir
|
|
178
|
+
|
|
179
|
+
masterHeaderView={masterHeaderView}
|
|
180
|
+
resourceHeaderContent={resourceHeaderContent}
|
|
181
|
+
/>
|
|
182
|
+
);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
export default App;
|
package/src/App.css
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
.App {
|
|
2
|
+
text-align: center;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.App-logo {
|
|
6
|
+
height: 40vmin;
|
|
7
|
+
pointer-events: none;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
11
|
+
.App-logo {
|
|
12
|
+
animation: App-logo-spin infinite 20s linear;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.App-header {
|
|
17
|
+
background-color: #282c34;
|
|
18
|
+
min-height: 100vh;
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
align-items: center;
|
|
22
|
+
justify-content: center;
|
|
23
|
+
font-size: calc(10px + 2vmin);
|
|
24
|
+
color: white;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.App-link {
|
|
28
|
+
color: #61dafb;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@keyframes App-logo-spin {
|
|
32
|
+
from {
|
|
33
|
+
transform: rotate(0deg);
|
|
34
|
+
}
|
|
35
|
+
to {
|
|
36
|
+
transform: rotate(360deg);
|
|
37
|
+
}
|
|
38
|
+
}
|
package/src/App.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// Gerekli kütüphaneleri import ediyoruz
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
// Timeline bileşenini import ediyoruz
|
|
4
|
+
import Timeline from "./components/Timeline/Timeline";
|
|
5
|
+
|
|
6
|
+
const App = () => {
|
|
7
|
+
// Timeline başlangıç tarihi (zorunlu, format: "YYYY-MM-DD")
|
|
8
|
+
const programDate = "2025-01-02";
|
|
9
|
+
|
|
10
|
+
// Timeline için etkinliklerin veri listesi
|
|
11
|
+
const events = [
|
|
12
|
+
{
|
|
13
|
+
id: "lux-101-1", // Benzersiz etkinlik kimliği (zorunlu)
|
|
14
|
+
title: "Room 101 Event", // Etkinlik adı (zorunlu)
|
|
15
|
+
startDate: new Date("2025-01-01"), // Başlangıç tarihi (zorunlu, JS Date formatı)
|
|
16
|
+
endDate: new Date("2025-01-08"), // Bitiş tarihi (zorunlu, JS Date formatı)
|
|
17
|
+
resourceId: "lux-101", // Hangi kaynağa ait olduğunu belirten ID (zorunlu)
|
|
18
|
+
color: "#ff5733", // Etkinlik için özel renk (isteğe bağlı)
|
|
19
|
+
totalAmount: 500, // Ek alan: Toplam borç (isteğe bağlı)
|
|
20
|
+
amountPaid: 200, // Ek alan: Ödenen miktar (isteğe bağlı)
|
|
21
|
+
status: "Confirmed", // Ek alan: Rezervasyon durumu (isteğe bağlı)
|
|
22
|
+
note: "Misafirler özel talep olarak ekstra yastık istediler.", // Not (isteğe bağlı)
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "lux-102-1",
|
|
26
|
+
title: "Room 102 Event",
|
|
27
|
+
startDate: new Date("2025-01-02"),
|
|
28
|
+
endDate: new Date("2025-01-04"),
|
|
29
|
+
resourceId: "lux-102",
|
|
30
|
+
color: "#33a1ff",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: "lux-103-1",
|
|
34
|
+
title: "Room 103 Event",
|
|
35
|
+
startDate: new Date("2025-01-01"),
|
|
36
|
+
endDate: new Date("2025-01-02"),
|
|
37
|
+
resourceId: "lux-103",
|
|
38
|
+
color: "#33ff57",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: "fam-201-1",
|
|
42
|
+
title: "Suite 201 Event",
|
|
43
|
+
startDate: new Date("2025-01-01"),
|
|
44
|
+
endDate: new Date("2025-01-02"),
|
|
45
|
+
resourceId: "fam-201",
|
|
46
|
+
color: "#ff33a1",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: "fam-202-1",
|
|
50
|
+
title: "Suite 202 Event",
|
|
51
|
+
startDate: new Date("2025-01-03"),
|
|
52
|
+
endDate: new Date("2025-01-05"),
|
|
53
|
+
resourceId: "fam-202",
|
|
54
|
+
color: "#a1ff33",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "bus-301-1",
|
|
58
|
+
title: "Room 301 Event",
|
|
59
|
+
startDate: new Date("2025-01-02"),
|
|
60
|
+
endDate: new Date("2025-01-04"),
|
|
61
|
+
resourceId: "bus-301",
|
|
62
|
+
color: "#ff9a00",
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: "vip-401-1",
|
|
66
|
+
title: "VIP 401 Event",
|
|
67
|
+
startDate: new Date("2025-01-04"),
|
|
68
|
+
endDate: new Date("2025-01-06"),
|
|
69
|
+
resourceId: "vip-401",
|
|
70
|
+
color: "#800080",
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: "vip-402-1",
|
|
74
|
+
title: "VIP 402 Event",
|
|
75
|
+
startDate: new Date("2025-01-05"),
|
|
76
|
+
endDate: new Date("2025-01-06"),
|
|
77
|
+
resourceId: "vip-402",
|
|
78
|
+
color: "#008080",
|
|
79
|
+
},
|
|
80
|
+
// Diğer etkinlikler...
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
// Kaynakların listesi (zorunlu, grup ve kaynak bilgisi içermeli)
|
|
84
|
+
const resources = [
|
|
85
|
+
{
|
|
86
|
+
groupName: "Luxury Rooms", // Grup adı (zorunlu)
|
|
87
|
+
resources: [
|
|
88
|
+
{ id: "lux-101", name: "Room 101" }, // Kaynak ID ve adı (zorunlu)
|
|
89
|
+
{ id: "lux-102", name: "Room 102" },
|
|
90
|
+
{ id: "lux-103", name: "Room 103" },
|
|
91
|
+
{ id: "lux-104", name: "Room 104" },
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
groupName: "Family Suites",
|
|
96
|
+
resources: [
|
|
97
|
+
{ id: "fam-201", name: "Suite 201" },
|
|
98
|
+
{ id: "fam-202", name: "Suite 202" },
|
|
99
|
+
{ id: "fam-203", name: "Suite 203" },
|
|
100
|
+
{ id: "fam-204", name: "Suite 204" },
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
groupName: "Business Class",
|
|
105
|
+
resources: [
|
|
106
|
+
{ id: "bus-301", name: "Room 301" },
|
|
107
|
+
{ id: "bus-302", name: "Room 302" },
|
|
108
|
+
{ id: "bus-303", name: "Room 303" },
|
|
109
|
+
{ id: "bus-304", name: "Room 304" },
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
groupName: "VIP Exclusive",
|
|
114
|
+
resources: [
|
|
115
|
+
{ id: "vip-401", name: "VIP 401" },
|
|
116
|
+
{ id: "vip-402", name: "VIP 402" },
|
|
117
|
+
{ id: "vip-403", name: "VIP 403" },
|
|
118
|
+
{ id: "vip-404", name: "VIP 404" },
|
|
119
|
+
|
|
120
|
+
],
|
|
121
|
+
},
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
// Kaynak ayarları (isteğe bağlı, varsayılan ayarlar mevcut)
|
|
125
|
+
const resourceSettings = {
|
|
126
|
+
showIdAsName: false, // true: Kaynak ID gösterir, false: Kaynak adı gösterir
|
|
127
|
+
isGrouped: true, // true: Kaynakları gruplar halinde gösterir
|
|
128
|
+
isCollapsible: true, // true: Gruplar açılıp kapatılabilir
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// Drag-and-drop işlemleri için gerekli callback ve state'ler
|
|
132
|
+
const [dropInfo, setDropInfo] = useState(null); // Sürükle-bırak sonrası bilgi saklar
|
|
133
|
+
const handleDragInfo = (dragData) => {
|
|
134
|
+
console.log("Dragged Event Info:", dragData);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// Etkinlik genişletme (extend) işlemi callback'i
|
|
138
|
+
const handleExtendInfo = (extendData) => {
|
|
139
|
+
console.log("Extended Event Info:", extendData);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// Yeni etkinlik oluşturma işlemi callback'i
|
|
143
|
+
const handleCreateEventInfo = (newEventData) => {
|
|
144
|
+
console.log("New Event Created:", newEventData);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// Etkinlik tıklama işlemi callback'i
|
|
148
|
+
const handleEventClick = (evt, ev) => {
|
|
149
|
+
console.log("Event clicked:", evt);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// Etkinlik sağ tıklama işlemi callback'i
|
|
153
|
+
const handleEventRightClick = (evt, ev) => {
|
|
154
|
+
ev.preventDefault(); // Varsayılan sağ tık menüsünü engeller
|
|
155
|
+
console.log("Event right-clicked:", evt);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// Diğer özellikler ve kontrol mekanizmaları
|
|
159
|
+
const eventsDragOn = true; // true: Etkinlik sürükle-bırak özelliği aktif
|
|
160
|
+
const eventsExtendOn = true; // true: Etkinlik genişletme özelliği aktif
|
|
161
|
+
const createNewEventOn = true; // true: Yeni etkinlik oluşturma özelliği aktif
|
|
162
|
+
const horizontalScrollOn = true; // true: Yatay kaydırma özelliği aktif
|
|
163
|
+
const [masterHeaderView, setMasterHeaderView] = useState(true); // true: Master Header gösterilir
|
|
164
|
+
const [resourceHeaderContent, setResourceHeaderContent] = useState("Akfa Timeline"); // Resources başlık içeriği
|
|
165
|
+
|
|
166
|
+
return (
|
|
167
|
+
<Timeline
|
|
168
|
+
// Kaynak verileri (zorunlu)
|
|
169
|
+
resources={resources}
|
|
170
|
+
// Kaynak ayarları (isteğe bağlı)
|
|
171
|
+
resourceSettings={resourceSettings}
|
|
172
|
+
// Timeline başlangıç tarihi (zorunlu)
|
|
173
|
+
programDate={programDate}
|
|
174
|
+
// Etkinlik verileri (zorunlu)
|
|
175
|
+
events={events}
|
|
176
|
+
externalEvents={events}
|
|
177
|
+
// Drop bilgisi için callback ve state
|
|
178
|
+
setDropInfo={setDropInfo}
|
|
179
|
+
dropInfo={dropInfo}
|
|
180
|
+
// Bugün göstergesi (isteğe bağlı)
|
|
181
|
+
indicatorOn={true}
|
|
182
|
+
// Sürükle-bırak ve genişletme özellikleri (isteğe bağlı)
|
|
183
|
+
eventsDragOn={eventsDragOn}
|
|
184
|
+
eventsExtendOn={eventsExtendOn}
|
|
185
|
+
createNewEventOn={createNewEventOn}
|
|
186
|
+
// Callback'ler
|
|
187
|
+
onDragInfo={handleDragInfo}
|
|
188
|
+
onExtendInfo={handleExtendInfo}
|
|
189
|
+
onCreateEventInfo={handleCreateEventInfo}
|
|
190
|
+
onEventClick={handleEventClick}
|
|
191
|
+
onEventRightClick={handleEventRightClick}
|
|
192
|
+
// Yatay kaydırma özelliği (isteğe bağlı)
|
|
193
|
+
horizontalScrollOn={horizontalScrollOn}
|
|
194
|
+
// Master Header görünürlüğü ve Resources başlığı içeriği
|
|
195
|
+
masterHeaderView={masterHeaderView}
|
|
196
|
+
resourceHeaderContent={resourceHeaderContent}
|
|
197
|
+
/>
|
|
198
|
+
);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export default App;
|
package/src/App.test.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "dd/mm/yyyy" formatındaki bir tarih string'ini Date objesine dönüştürür.
|
|
3
|
+
* Eğer dateInput bir string değilse, direkt Date objesini döndürür.
|
|
4
|
+
* @param {string | Object | Date} dateInput - "dd/mm/yyyy" formatında tarih stringi veya {fullDate: Date, display: string} objesi veya Date objesi.
|
|
5
|
+
* @returns {Date} - Date objesi.
|
|
6
|
+
*/
|
|
7
|
+
export const parseDate = (dateInput) => {
|
|
8
|
+
if (dateInput instanceof Date) {
|
|
9
|
+
return dateInput;
|
|
10
|
+
}
|
|
11
|
+
if (typeof dateInput === 'string') {
|
|
12
|
+
const [day, month, year] = dateInput.split("/").map(Number);
|
|
13
|
+
return new Date(year, month - 1, day);
|
|
14
|
+
} else if (typeof dateInput === 'object' && dateInput.fullDate instanceof Date) {
|
|
15
|
+
return new Date(dateInput.fullDate);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
console.error("parseDate received invalid input:", dateInput);
|
|
19
|
+
return new Date(); // veya hata fırlat
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Bir tarihin belirli bir aralık içinde olup olmadığını kontrol eder.
|
|
25
|
+
* @param {string | Object | Date} date - "dd/mm/yyyy" formatında tarih stringi, {fullDate: Date, display: string} objesi veya Date objesi.
|
|
26
|
+
* @param {string | Object | Date} startDate - "dd/mm/yyyy" formatında başlangıç tarihi stringi, {fullDate: Date, display: string} objesi veya Date objesi.
|
|
27
|
+
* @param {string | Object | Date} endDate - "dd/mm/yyyy" formatında bitiş tarihi stringi, {fullDate: Date, display: string} objesi veya Date objesi.
|
|
28
|
+
* @returns {boolean} - Tarih aralık içinde ise true, değilse false.
|
|
29
|
+
*/
|
|
30
|
+
export const isDateInRange = (date, startDate, endDate) => {
|
|
31
|
+
const d = parseDate(date);
|
|
32
|
+
const start = parseDate(startDate);
|
|
33
|
+
const end = parseDate(endDate);
|
|
34
|
+
return d >= start && d <= end;
|
|
35
|
+
};
|