akfatimeline 1.0.0 → 1.0.4

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.
Files changed (39) hide show
  1. package/.babelrc +6 -0
  2. package/CHANGELOG.md +35 -0
  3. package/dist/Timeline.js +2292 -0
  4. package/dist/dist/components/Timeline/DragAndDropHandler.js +35 -0
  5. package/dist/dist/components/Timeline/EventTooltip.js +206 -0
  6. package/dist/dist/components/Timeline/Indicator.js +30 -0
  7. package/dist/dist/components/Timeline/MasterHeader.js +55 -0
  8. package/dist/dist/components/Timeline/Resources.js +53 -0
  9. package/dist/dist/components/Timeline/ResourcesHeader.js +14 -0
  10. package/dist/dist/components/Timeline/Timeline.css +534 -0
  11. package/dist/dist/components/Timeline/Timeline.js +277 -0
  12. package/dist/dist/components/Timeline/TimelineCell.js +8 -0
  13. package/dist/dist/components/Timeline/TimelineContent.js +422 -0
  14. package/dist/dist/components/Timeline/TimelineEvents.js +114 -0
  15. package/dist/dist/components/Timeline/TimelineHeader.js +43 -0
  16. package/dist/dist/components/Timeline/TimelineMonthContainer.js +29 -0
  17. package/dist/dist/components/Timeline/TimelineResources.js +16 -0
  18. package/dist/dist/hooks/useDragAndDrop.js +80 -0
  19. package/dist/dist/hooks/useEventDragDrop.js +120 -0
  20. package/dist/dist/hooks/useExtendEvent.js +28 -0
  21. package/dist/dist/utils/HorizontalVirtualScroll.js +0 -0
  22. package/dist/dist/utils/dateUtils.js +36 -0
  23. package/dist/dist/utils/filterTimelineData.js +21 -0
  24. package/dist/dist/utils/timelineUtils.js +40 -0
  25. package/package.json +20 -1
  26. package/public/index kutuphane /304/261c/304/261n.html" +43 -0
  27. package/public/index tasarim icin.html +20 -0
  28. package/src/App.js +161 -154
  29. package/src/components/Timeline/DatePickerComponent.js +17 -0
  30. package/src/components/Timeline/EventTooltip.js +1 -1
  31. package/src/components/Timeline/Indicator.js +1 -2
  32. package/src/components/Timeline/MasterHeader.js +36 -23
  33. package/src/components/Timeline/Timeline.css +90 -8
  34. package/src/components/Timeline/Timeline.js +71 -44
  35. package/src/components/Timeline/TimelineContent.js +154 -129
  36. package/src/hooks/useEventDragDrop.js +22 -16
  37. package/webpack.config.js +25 -7
  38. package/src/App copy.js +0 -185
  39. package/src/components/Timeline/TimelineContent copy.js +0 -421
@@ -0,0 +1,80 @@
1
+ // src/hooks/useDragAndDrop.js
2
+ import { useState } from "react";
3
+ import { parseDate } from "../utils/dateUtils"; // Named import
4
+
5
+ const useDragAndDrop = (initialEvents = []) => {
6
+ const [isDragging, setIsDragging] = useState(false);
7
+ const [dragStart, setDragStart] = useState(null);
8
+ const [dragEnd, setDragEnd] = useState(null);
9
+ const [events, setEvents] = useState(initialEvents);
10
+
11
+ // Sürükleme başlat
12
+ const startDrag = (resourceId, date) => {
13
+ setIsDragging(true);
14
+ setDragStart({ resourceId, date });
15
+ setDragEnd({ resourceId, date });
16
+ };
17
+
18
+ // Sürükleme hareketi
19
+ const updateDrag = (resourceId, date) => {
20
+ if (!isDragging) return;
21
+ setDragEnd({ resourceId, date });
22
+ };
23
+
24
+ // Sürükleme bitişi
25
+ const endDrag = (dates) => {
26
+ if (!isDragging || !dragStart || !dragEnd) return;
27
+ if (dragStart.resourceId !== dragEnd.resourceId) {
28
+ resetDrag();
29
+ return;
30
+ }
31
+
32
+ const startDateIndex = dates.findIndex(
33
+ (d) => parseDate(d.fullDate).toDateString() === parseDate(dragStart.date.fullDate).toDateString()
34
+ );
35
+ const endDateIndex = dates.findIndex(
36
+ (d) => parseDate(d.fullDate).toDateString() === parseDate(dragEnd.date.fullDate).toDateString()
37
+ );
38
+
39
+ if (startDateIndex === -1 || endDateIndex === -1) {
40
+ resetDrag();
41
+ return;
42
+ }
43
+
44
+ const sortedStartIndex = Math.min(startDateIndex, endDateIndex);
45
+ const sortedEndIndex = Math.max(startDateIndex, endDateIndex);
46
+ const startDate = dates[sortedStartIndex].fullDate;
47
+ const endDate = dates[sortedEndIndex].fullDate;
48
+
49
+ const newEvent = {
50
+ id: Date.now(),
51
+ title: "Yeni Etkinlik",
52
+ resourceId: dragStart.resourceId,
53
+ startDate: startDate,
54
+ endDate: endDate,
55
+ color: "#ff7f50",
56
+ };
57
+
58
+ setEvents((prev) => [...prev, newEvent]);
59
+ resetDrag();
60
+ };
61
+
62
+ const resetDrag = () => {
63
+ setIsDragging(false);
64
+ setDragStart(null);
65
+ setDragEnd(null);
66
+ };
67
+
68
+ return {
69
+ events,
70
+ isDragging,
71
+ dragStart,
72
+ dragEnd,
73
+ startDrag,
74
+ updateDrag,
75
+ endDrag,
76
+ setEvents,
77
+ };
78
+ };
79
+
80
+ export default useDragAndDrop;
@@ -0,0 +1,120 @@
1
+ import { useState } from "react";
2
+
3
+ const useEventDragDrop = (events, setEvents, setDropInfo) => {
4
+ const [draggingEvent, setDraggingEvent] = useState(null);
5
+ const [dragOffset, setDragOffset] = useState(0);
6
+ const [mode, setMode] = useState(null); // "drag" veya "extend"
7
+
8
+ const handleDragStart = (event, eventId) => {
9
+ if (mode === "extend") return; // Uzatma modundaysa taşıma işlemini başlatma
10
+
11
+ event.stopPropagation();
12
+
13
+ const eventElement = event.target;
14
+ const eventRect = eventElement.getBoundingClientRect();
15
+ const offset = event.clientX - eventRect.left;
16
+
17
+ setDraggingEvent(eventId);
18
+ setDragOffset(offset);
19
+ setMode("drag"); // Modu taşıma olarak ayarla
20
+
21
+ const draggedEvent = events.find((evt) => evt.id === eventId);
22
+ if (draggedEvent) {
23
+ console.log("Dragging Event Start:", draggedEvent.startDate);
24
+ console.log("Dragging Event End:", draggedEvent.endDate);
25
+ }
26
+ };
27
+
28
+ const handleExtendStart = (event, eventId) => {
29
+ event.stopPropagation();
30
+
31
+ setDraggingEvent(eventId);
32
+ setMode("extend"); // Modu uzatma olarak ayarla
33
+ };
34
+
35
+ const handleDragOver = (event) => {
36
+ event.preventDefault();
37
+ };
38
+
39
+ const handleDrop = (event, resourceId, targetDate) => {
40
+ event.preventDefault();
41
+
42
+ if (mode === "drag" && draggingEvent) {
43
+ const draggedEvent = events.find((evt) => evt.id === draggingEvent);
44
+
45
+ if (draggedEvent) {
46
+ const duration = draggedEvent.endDate - draggedEvent.startDate;
47
+ const cellWidth = event.target.offsetWidth || 30;
48
+ const offsetDays = Math.floor(dragOffset / cellWidth);
49
+ const newStartDate = new Date(targetDate.getTime() - offsetDays * 24 * 60 * 60 * 1000);
50
+ const newEndDate = new Date(newStartDate.getTime() + duration);
51
+
52
+ console.log("New Start Date:", newStartDate);
53
+ console.log("New End Date:", newEndDate);
54
+
55
+ setEvents((prevEvents) =>
56
+ prevEvents.map((evt) =>
57
+ evt.id === draggingEvent
58
+ ? {
59
+ ...evt,
60
+ resourceId,
61
+ startDate: newStartDate,
62
+ endDate: newEndDate,
63
+ }
64
+ : evt
65
+ )
66
+ );
67
+
68
+ if (setDropInfo) {
69
+ setDropInfo({
70
+ id: draggingEvent,
71
+ newResourceId: resourceId,
72
+ newStartDate,
73
+ newEndDate,
74
+ });
75
+ }
76
+ }
77
+ }
78
+
79
+ setDraggingEvent(null);
80
+ setDragOffset(0);
81
+ setMode(null);
82
+ };
83
+
84
+ const handleExtend = (event, eventId, newEndDate) => {
85
+ if (mode !== "extend" || draggingEvent !== eventId) return;
86
+
87
+ setEvents((prevEvents) =>
88
+ prevEvents.map((evt) =>
89
+ evt.id === eventId
90
+ ? {
91
+ ...evt,
92
+ endDate: newEndDate,
93
+ }
94
+ : evt
95
+ )
96
+ );
97
+
98
+ console.log("Extended Event ID:", eventId, "New End Date:", newEndDate);
99
+
100
+ setDraggingEvent(null);
101
+ setMode(null);
102
+ };
103
+
104
+ const handleDragEnd = () => {
105
+ setDraggingEvent(null);
106
+ setDragOffset(0);
107
+ setMode(null);
108
+ };
109
+
110
+ return {
111
+ handleDragStart,
112
+ handleExtendStart,
113
+ handleDragOver,
114
+ handleDrop,
115
+ handleExtend,
116
+ handleDragEnd,
117
+ };
118
+ };
119
+
120
+ export default useEventDragDrop;
@@ -0,0 +1,28 @@
1
+ import { useCallback } from "react";
2
+
3
+ const useExtendEvent = (events, setEvents) => {
4
+ /**
5
+ * Etkinliği uzatmak veya kısaltmak için kullanılan işlev.
6
+ * @param {number} eventId - Güncellenmesi gereken etkinliğin ID'si.
7
+ * @param {Date} newEndDate - Etkinliğin yeni bitiş tarihi.
8
+ */
9
+ const extendEvent = useCallback(
10
+ (eventId, newEndDate) => {
11
+ setEvents((prevEvents) =>
12
+ prevEvents.map((event) =>
13
+ event.id === eventId
14
+ ? {
15
+ ...event,
16
+ endDate: newEndDate, // Yeni bitiş tarihini günceller
17
+ }
18
+ : event // Diğer etkinlikler aynı kalır
19
+ )
20
+ );
21
+ },
22
+ [setEvents]
23
+ );
24
+
25
+ return { extendEvent };
26
+ };
27
+
28
+ export default useExtendEvent;
File without changes
@@ -0,0 +1,36 @@
1
+ // src/utils/dateUtils.js
2
+
3
+ /**
4
+ * "dd/mm/yyyy" formatındaki bir tarih string'ini Date objesine dönüştürür.
5
+ * Eğer dateInput bir string değilse, direkt Date objesini döndürür.
6
+ * @param {string | Object | Date} dateInput - "dd/mm/yyyy" formatında tarih stringi veya {fullDate: Date, display: string} objesi veya Date objesi.
7
+ * @returns {Date} - Date objesi.
8
+ */
9
+ export const parseDate = (dateInput) => {
10
+ if (dateInput instanceof Date) {
11
+ return dateInput;
12
+ }
13
+ if (typeof dateInput === 'string') {
14
+ const [day, month, year] = dateInput.split("/").map(Number);
15
+ return new Date(year, month - 1, day);
16
+ } else if (typeof dateInput === 'object' && dateInput.fullDate instanceof Date) {
17
+ return new Date(dateInput.fullDate.getTime() + dateInput.fullDate.getTimezoneOffset() * 60000);
18
+ } else {
19
+ console.error("parseDate received invalid input:", dateInput);
20
+ return new Date(); // veya hata fırlat
21
+ }
22
+ };
23
+
24
+ /**
25
+ * Bir tarihin belirli bir aralık içinde olup olmadığını kontrol eder.
26
+ * @param {string | Object | Date} date - "dd/mm/yyyy" formatında tarih stringi, {fullDate: Date, display: string} objesi veya Date objesi.
27
+ * @param {string | Object | Date} startDate - "dd/mm/yyyy" formatında başlangıç tarihi stringi, {fullDate: Date, display: string} objesi veya Date objesi.
28
+ * @param {string | Object | Date} endDate - "dd/mm/yyyy" formatında bitiş tarihi stringi, {fullDate: Date, display: string} objesi veya Date objesi.
29
+ * @returns {boolean} - Tarih aralık içinde ise true, değilse false.
30
+ */
31
+ export const isDateInRange = (date, startDate, endDate) => {
32
+ const d = parseDate(date);
33
+ const start = parseDate(startDate);
34
+ const end = parseDate(endDate);
35
+ return d >= start && d <= end;
36
+ };
@@ -0,0 +1,21 @@
1
+ const filterTimelineData = (dates, startDate, dayCount) => {
2
+ const startIndex = dates.findIndex(
3
+ (date) => date.fullDate.toISOString().split("T")[0] === startDate
4
+ );
5
+
6
+ if (startIndex === -1) {
7
+ console.warn("Seçilen başlangıç tarihi bulunamadı.");
8
+ return { filteredDates: [] };
9
+ }
10
+
11
+ const filteredDates = dates.slice(startIndex, startIndex + dayCount);
12
+
13
+ return {
14
+ filteredDates,
15
+ startIndex,
16
+ endIndex: startIndex + dayCount - 1,
17
+ };
18
+ };
19
+
20
+ export default filterTimelineData;
21
+
@@ -0,0 +1,40 @@
1
+ // src/utils/timelineUtils.js
2
+
3
+ export const generateTimelineData = (startYear, endYear) => {
4
+ const dayNames = ["Paz", "Pzt", "Sal", "Çar", "Per", "Cum", "Cmt"];
5
+ const monthNames = [
6
+ "Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran",
7
+ "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık",
8
+ ];
9
+
10
+ const dates = [];
11
+ const monthHeaders = [];
12
+
13
+ for (let year = startYear; year <= endYear; year++) {
14
+ for (let month = 1; month <= 12; month++) {
15
+ const daysInMonth = new Date(year, month, 0).getDate();
16
+ const startIndex = dates.length;
17
+
18
+ for (let day = 1; day <= daysInMonth; day++) {
19
+ const date = new Date(year, month - 1, day);
20
+ const dayName = dayNames[date.getDay()];
21
+ dates.push({
22
+ fullDate: date,
23
+ display: `${day} ${dayName}`,
24
+ });
25
+ }
26
+
27
+ const endIndex = dates.length - 1;
28
+ monthHeaders.push({
29
+ monthName: monthNames[month - 1],
30
+ year,
31
+ startIndex,
32
+ endIndex,
33
+ totalDays: endIndex - startIndex + 1,
34
+ });
35
+ }
36
+ }
37
+
38
+ return { dates, monthHeaders };
39
+ };
40
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akfatimeline",
3
- "version": "1.0.0",
3
+ "version": "1.0.4",
4
4
  "description": "A customizable timeline component for React applications",
5
5
  "main": "dist/Timeline.js",
6
6
  "module": "dist/Timeline.js",
@@ -46,5 +46,24 @@
46
46
  "last 1 firefox version",
47
47
  "last 1 safari version"
48
48
  ]
49
+ },
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "https://github.com/AKFAPLUS/akfatimeline.git"
53
+ },
54
+ "bugs": {
55
+ "url": "https://github.com/AKFAPLUS/akfatimeline/issues"
56
+ },
57
+ "homepage": "https://github.com/AKFAPLUS/akfatimeline#readme",
58
+ "devDependencies": {
59
+ "@babel/core": "^7.26.0",
60
+ "@babel/preset-env": "^7.26.0",
61
+ "@babel/preset-react": "^7.26.3",
62
+ "babel-loader": "^9.2.1",
63
+ "copy-webpack-plugin": "^12.0.2",
64
+ "css-loader": "^7.1.2",
65
+ "style-loader": "^4.0.0",
66
+ "webpack": "^5.97.1",
67
+ "webpack-cli": "^6.0.1"
49
68
  }
50
69
  }
@@ -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>
@@ -0,0 +1,20 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <link rel="icon" href="/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="/logo192.png" />
13
+ <link rel="manifest" href="/manifest.json" />
14
+ <title>React App</title>
15
+ </head>
16
+ <body>
17
+ <noscript>You need to enable JavaScript to run this app.</noscript>
18
+ <div id="root"></div>
19
+ </body>
20
+ </html>