akfatimeline 1.0.6 → 1.2.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.
Files changed (128) hide show
  1. package/CHANGELOG.md +98 -35
  2. package/dist/Timeline.js +4309 -1677
  3. package/dist/components/Timeline/AutocompleteSelect.js +150 -0
  4. package/dist/components/Timeline/ContextMenu.js +149 -0
  5. package/dist/components/Timeline/DailyView.js +255 -0
  6. package/dist/components/Timeline/DatePickerComponent.js +13 -0
  7. package/{public/dist/dist → dist}/components/Timeline/DragAndDropHandler.js +34 -34
  8. package/dist/components/Timeline/EventBadge.js +26 -0
  9. package/dist/components/Timeline/EventDetailModal.js +138 -0
  10. package/dist/components/Timeline/EventIcon.js +47 -0
  11. package/dist/{dist/components → components}/Timeline/EventTooltip.js +206 -206
  12. package/dist/components/Timeline/FilterPanel.js +179 -0
  13. package/dist/{dist/components → components}/Timeline/Indicator.js +26 -26
  14. package/dist/components/Timeline/LoadingSpinner.js +48 -0
  15. package/dist/{dist/components → components}/Timeline/MasterHeader.js +104 -68
  16. package/{public/dist/dist → dist}/components/Timeline/Resources.js +53 -53
  17. package/dist/{dist/components → components}/Timeline/ResourcesHeader.js +14 -14
  18. package/dist/components/Timeline/Timeline.css +2491 -0
  19. package/dist/components/Timeline/Timeline.js +607 -0
  20. package/dist/{dist/components → components}/Timeline/TimelineCell.js +8 -8
  21. package/dist/components/Timeline/TimelineContent.js +838 -0
  22. package/{public/dist/dist → dist}/components/Timeline/TimelineEvents.js +114 -114
  23. package/dist/components/Timeline/TimelineHeader.js +54 -0
  24. package/{public/dist/dist → dist}/components/Timeline/TimelineMonthContainer.js +29 -29
  25. package/{public/dist/dist → dist}/components/Timeline/TimelineResources.js +16 -16
  26. package/{public/dist/dist → dist}/hooks/useDragAndDrop.js +80 -80
  27. package/dist/{dist/hooks → hooks}/useEventDragDrop.js +126 -126
  28. package/dist/hooks/useEventManagement.js +173 -0
  29. package/dist/hooks/useEventSelection.js +82 -0
  30. package/{public/dist/dist → dist}/hooks/useExtendEvent.js +28 -28
  31. package/dist/hooks/useKeyboardShortcuts.js +158 -0
  32. package/dist/hooks/useTouchGestures.js +90 -0
  33. package/dist/utils/conflictUtils.js +105 -0
  34. package/dist/{dist/utils → utils}/dateUtils.js +36 -36
  35. package/dist/{dist/utils → utils}/filterTimelineData.js +20 -20
  36. package/dist/utils/filterUtils.js +106 -0
  37. package/dist/utils/timeUtils.js +179 -0
  38. package/dist/{dist/utils → utils}/timelineUtils.js +39 -39
  39. package/dist/utils/viewModeUtils.js +54 -0
  40. package/package.json +89 -19
  41. package/src/App.js +300 -19
  42. package/src/components/Timeline/AutocompleteSelect.js +150 -0
  43. package/src/components/Timeline/ContextMenu.js +149 -0
  44. package/src/components/Timeline/DailyView.js +255 -0
  45. package/src/components/Timeline/DatePickerComponent.js +13 -17
  46. package/src/components/Timeline/DragAndDropHandler.js +34 -34
  47. package/src/components/Timeline/EventBadge.js +26 -0
  48. package/src/components/Timeline/EventDetailModal.js +138 -0
  49. package/src/components/Timeline/EventIcon.js +47 -0
  50. package/src/components/Timeline/EventTooltip.js +206 -206
  51. package/src/components/Timeline/FilterPanel.js +179 -0
  52. package/src/components/Timeline/Indicator.js +26 -26
  53. package/src/components/Timeline/LoadingSpinner.js +48 -0
  54. package/src/components/Timeline/MasterHeader.js +104 -68
  55. package/src/components/Timeline/Resources.js +53 -53
  56. package/src/components/Timeline/ResourcesHeader.js +14 -14
  57. package/src/components/Timeline/Timeline.css +2491 -616
  58. package/src/components/Timeline/Timeline.js +607 -309
  59. package/src/components/Timeline/TimelineCell.js +8 -8
  60. package/src/components/Timeline/TimelineContent.js +838 -446
  61. package/src/components/Timeline/TimelineEvents.js +114 -114
  62. package/src/components/Timeline/TimelineHeader.js +54 -43
  63. package/src/components/Timeline/TimelineMonthContainer.js +29 -29
  64. package/src/components/Timeline/TimelineResources.js +16 -16
  65. package/src/demo.css +4 -0
  66. package/src/hooks/useDragAndDrop.js +80 -80
  67. package/src/hooks/useEventDragDrop.js +126 -126
  68. package/src/hooks/useEventManagement.js +173 -0
  69. package/src/hooks/useEventSelection.js +82 -0
  70. package/src/hooks/useExtendEvent.js +28 -28
  71. package/src/hooks/useKeyboardShortcuts.js +158 -0
  72. package/src/hooks/useTouchGestures.js +90 -0
  73. package/src/index.js +1 -7
  74. package/src/library.js +26 -0
  75. package/src/utils/conflictUtils.js +105 -0
  76. package/src/utils/dateUtils.js +36 -36
  77. package/src/utils/filterTimelineData.js +20 -20
  78. package/src/utils/filterUtils.js +106 -0
  79. package/src/utils/timeUtils.js +179 -0
  80. package/src/utils/timelineUtils.js +39 -39
  81. package/src/utils/viewModeUtils.js +54 -0
  82. package/.babelrc +0 -6
  83. package/babel.config.json +0 -4
  84. package/dist/dist/components/Timeline/DatePickerComponent.js +0 -17
  85. package/dist/dist/components/Timeline/DragAndDropHandler.js +0 -35
  86. package/dist/dist/components/Timeline/Resources.js +0 -53
  87. package/dist/dist/components/Timeline/Timeline.css +0 -616
  88. package/dist/dist/components/Timeline/Timeline.js +0 -309
  89. package/dist/dist/components/Timeline/TimelineContent.js +0 -446
  90. package/dist/dist/components/Timeline/TimelineEvents.js +0 -114
  91. package/dist/dist/components/Timeline/TimelineHeader.js +0 -43
  92. package/dist/dist/components/Timeline/TimelineMonthContainer.js +0 -29
  93. package/dist/dist/components/Timeline/TimelineResources.js +0 -16
  94. package/dist/dist/hooks/useDragAndDrop.js +0 -80
  95. package/dist/dist/hooks/useExtendEvent.js +0 -28
  96. package/public/dist/Timeline.js +0 -3277
  97. package/public/dist/dist/components/Timeline/DatePickerComponent.js +0 -17
  98. package/public/dist/dist/components/Timeline/EventTooltip.js +0 -206
  99. package/public/dist/dist/components/Timeline/Indicator.js +0 -29
  100. package/public/dist/dist/components/Timeline/MasterHeader.js +0 -68
  101. package/public/dist/dist/components/Timeline/ResourcesHeader.js +0 -14
  102. package/public/dist/dist/components/Timeline/Timeline.css +0 -616
  103. package/public/dist/dist/components/Timeline/Timeline.js +0 -304
  104. package/public/dist/dist/components/Timeline/TimelineCell.js +0 -8
  105. package/public/dist/dist/components/Timeline/TimelineContent.js +0 -447
  106. package/public/dist/dist/components/Timeline/TimelineHeader.js +0 -43
  107. package/public/dist/dist/hooks/useEventDragDrop.js +0 -126
  108. package/public/dist/dist/utils/HorizontalVirtualScroll.js +0 -0
  109. package/public/dist/dist/utils/dateUtils.js +0 -36
  110. package/public/dist/dist/utils/filterTimelineData.js +0 -21
  111. package/public/dist/dist/utils/timelineUtils.js +0 -40
  112. package/public/favicon.ico +0 -0
  113. package/public/index kutuphane /304/261c/304/261n.html" +0 -43
  114. package/public/index tasarim icin.html +0 -20
  115. package/public/index.html +0 -43
  116. package/public/logo192.png +0 -0
  117. package/public/logo512.png +0 -0
  118. package/public/manifest.json +0 -25
  119. package/public/robots.txt +0 -3
  120. package/src/App.css +0 -38
  121. package/src/App.test.js +0 -8
  122. package/src/dist/Timeline.js +0 -277
  123. package/src/index.css +0 -13
  124. package/src/logo.svg +0 -1
  125. package/src/reportWebVitals.js +0 -13
  126. package/src/setupTests.js +0 -5
  127. package/webpack.config.js +0 -49
  128. /package/dist/{dist/utils → utils}/HorizontalVirtualScroll.js +0 -0
@@ -0,0 +1,158 @@
1
+ import { useEffect, useCallback } from 'react';
2
+
3
+ /**
4
+ * Keyboard shortcuts hook
5
+ * @param {Object} config - Keyboard shortcuts configuration
6
+ * @param {Function} config.onNavigateLeft - Left arrow key handler
7
+ * @param {Function} config.onNavigateRight - Right arrow key handler
8
+ * @param {Function} config.onNavigateUp - Up arrow key handler
9
+ * @param {Function} config.onNavigateDown - Down arrow key handler
10
+ * @param {Function} config.onDelete - Delete key handler
11
+ * @param {Function} config.onUndo - Ctrl+Z handler
12
+ * @param {Function} config.onRedo - Ctrl+Y handler
13
+ * @param {Function} config.onCopy - Ctrl+C handler
14
+ * @param {Function} config.onPaste - Ctrl+V handler
15
+ * @param {Function} config.onZoomIn - Ctrl+= or Ctrl++ handler
16
+ * @param {Function} config.onZoomOut - Ctrl+- handler
17
+ * @param {Object} config.keyMap - Custom key mappings (optional)
18
+ * @param {boolean} config.enabled - Enable/disable shortcuts
19
+ */
20
+ const useKeyboardShortcuts = ({
21
+ onNavigateLeft,
22
+ onNavigateRight,
23
+ onNavigateUp,
24
+ onNavigateDown,
25
+ onDelete,
26
+ onUndo,
27
+ onRedo,
28
+ onCopy,
29
+ onPaste,
30
+ onZoomIn,
31
+ onZoomOut,
32
+ keyMap = {},
33
+ enabled = true,
34
+ }) => {
35
+ // Default key mappings
36
+ const defaultKeyMap = {
37
+ navigateLeft: keyMap.navigateLeft || 'ArrowLeft',
38
+ navigateRight: keyMap.navigateRight || 'ArrowRight',
39
+ navigateUp: keyMap.navigateUp || 'ArrowUp',
40
+ navigateDown: keyMap.navigateDown || 'ArrowDown',
41
+ delete: keyMap.delete || 'Delete',
42
+ undo: keyMap.undo || { key: 'z', ctrl: true },
43
+ redo: keyMap.redo || { key: 'y', ctrl: true },
44
+ copy: keyMap.copy || { key: 'c', ctrl: true },
45
+ paste: keyMap.paste || { key: 'v', ctrl: true },
46
+ zoomIn: keyMap.zoomIn || { key: '=', ctrl: true },
47
+ zoomOut: keyMap.zoomOut || { key: '-', ctrl: true },
48
+ };
49
+
50
+ const handleKeyDown = useCallback(
51
+ (e) => {
52
+ if (!enabled) return;
53
+
54
+ const key = e.key;
55
+ const isCtrl = e.ctrlKey || e.metaKey; // Mac için cmd tuşu desteği
56
+
57
+ // Arrow keys
58
+ if (key === defaultKeyMap.navigateLeft && onNavigateLeft) {
59
+ e.preventDefault();
60
+ onNavigateLeft();
61
+ } else if (key === defaultKeyMap.navigateRight && onNavigateRight) {
62
+ e.preventDefault();
63
+ onNavigateRight();
64
+ } else if (key === defaultKeyMap.navigateUp && onNavigateUp) {
65
+ e.preventDefault();
66
+ onNavigateUp();
67
+ } else if (key === defaultKeyMap.navigateDown && onNavigateDown) {
68
+ e.preventDefault();
69
+ onNavigateDown();
70
+ }
71
+ // Delete key
72
+ else if (key === defaultKeyMap.delete && onDelete) {
73
+ e.preventDefault();
74
+ onDelete();
75
+ }
76
+ // Ctrl+Z (Undo)
77
+ else if (
78
+ isCtrl &&
79
+ key.toLowerCase() === defaultKeyMap.undo.key.toLowerCase() &&
80
+ onUndo
81
+ ) {
82
+ e.preventDefault();
83
+ onUndo();
84
+ }
85
+ // Ctrl+Y (Redo)
86
+ else if (
87
+ isCtrl &&
88
+ key.toLowerCase() === defaultKeyMap.redo.key.toLowerCase() &&
89
+ onRedo
90
+ ) {
91
+ e.preventDefault();
92
+ onRedo();
93
+ }
94
+ // Ctrl+C (Copy)
95
+ else if (
96
+ isCtrl &&
97
+ key.toLowerCase() === defaultKeyMap.copy.key.toLowerCase() &&
98
+ onCopy
99
+ ) {
100
+ e.preventDefault();
101
+ onCopy();
102
+ }
103
+ // Ctrl+V (Paste)
104
+ else if (
105
+ isCtrl &&
106
+ key.toLowerCase() === defaultKeyMap.paste.key.toLowerCase() &&
107
+ onPaste
108
+ ) {
109
+ e.preventDefault();
110
+ onPaste();
111
+ }
112
+ // Ctrl+= or Ctrl++ (Zoom In)
113
+ else if (
114
+ isCtrl &&
115
+ (key === '=' || key === '+' || (key === '=' && e.shiftKey)) &&
116
+ onZoomIn
117
+ ) {
118
+ e.preventDefault();
119
+ onZoomIn();
120
+ }
121
+ // Ctrl+- (Zoom Out)
122
+ else if (
123
+ isCtrl &&
124
+ key === '-' &&
125
+ onZoomOut
126
+ ) {
127
+ e.preventDefault();
128
+ onZoomOut();
129
+ }
130
+ },
131
+ [
132
+ enabled,
133
+ defaultKeyMap,
134
+ onNavigateLeft,
135
+ onNavigateRight,
136
+ onNavigateUp,
137
+ onNavigateDown,
138
+ onDelete,
139
+ onUndo,
140
+ onRedo,
141
+ onCopy,
142
+ onPaste,
143
+ onZoomIn,
144
+ onZoomOut,
145
+ ]
146
+ );
147
+
148
+ useEffect(() => {
149
+ if (enabled) {
150
+ window.addEventListener('keydown', handleKeyDown);
151
+ return () => {
152
+ window.removeEventListener('keydown', handleKeyDown);
153
+ };
154
+ }
155
+ }, [enabled, handleKeyDown]);
156
+ };
157
+
158
+ export default useKeyboardShortcuts;
@@ -0,0 +1,90 @@
1
+ // src/hooks/useTouchGestures.js
2
+
3
+ import { useRef, useCallback } from 'react';
4
+
5
+ /**
6
+ * Touch gesture hook for mobile support
7
+ * @param {Object} handlers - Gesture handlers
8
+ * @returns {Object} - Touch event handlers
9
+ */
10
+ export const useTouchGestures = ({
11
+ onSwipeLeft,
12
+ onSwipeRight,
13
+ onSwipeUp,
14
+ onSwipeDown,
15
+ onPinch,
16
+ minSwipeDistance = 50,
17
+ enabled = true,
18
+ }) => {
19
+ const touchStartRef = useRef(null);
20
+ const touchStartTimeRef = useRef(null);
21
+ const lastTouchRef = useRef(null);
22
+
23
+ const handleTouchStart = useCallback((e) => {
24
+ if (!enabled) return;
25
+
26
+ const touch = e.touches[0];
27
+ touchStartRef.current = {
28
+ x: touch.clientX,
29
+ y: touch.clientY,
30
+ };
31
+ touchStartTimeRef.current = Date.now();
32
+ lastTouchRef.current = {
33
+ x: touch.clientX,
34
+ y: touch.clientY,
35
+ };
36
+ }, [enabled]);
37
+
38
+ const handleTouchMove = useCallback((e) => {
39
+ if (!enabled || !touchStartRef.current) return;
40
+
41
+ const touch = e.touches[0];
42
+ if (lastTouchRef.current) {
43
+ lastTouchRef.current = {
44
+ x: touch.clientX,
45
+ y: touch.clientY,
46
+ };
47
+ }
48
+ }, [enabled]);
49
+
50
+ const handleTouchEnd = useCallback((e) => {
51
+ if (!enabled || !touchStartRef.current || !lastTouchRef.current) return;
52
+
53
+ const touchEnd = e.changedTouches[0];
54
+ const deltaX = touchEnd.clientX - touchStartRef.current.x;
55
+ const deltaY = touchEnd.clientY - touchStartRef.current.y;
56
+ const deltaTime = Date.now() - touchStartTimeRef.current;
57
+
58
+ const absDeltaX = Math.abs(deltaX);
59
+ const absDeltaY = Math.abs(deltaY);
60
+
61
+ // Hızlı swipe kontrolü (300ms içinde)
62
+ if (deltaTime < 300 && (absDeltaX > minSwipeDistance || absDeltaY > minSwipeDistance)) {
63
+ if (absDeltaX > absDeltaY) {
64
+ // Yatay swipe
65
+ if (deltaX > 0 && onSwipeRight) {
66
+ onSwipeRight();
67
+ } else if (deltaX < 0 && onSwipeLeft) {
68
+ onSwipeLeft();
69
+ }
70
+ } else {
71
+ // Dikey swipe
72
+ if (deltaY > 0 && onSwipeDown) {
73
+ onSwipeDown();
74
+ } else if (deltaY < 0 && onSwipeUp) {
75
+ onSwipeUp();
76
+ }
77
+ }
78
+ }
79
+
80
+ touchStartRef.current = null;
81
+ lastTouchRef.current = null;
82
+ }, [enabled, minSwipeDistance, onSwipeLeft, onSwipeRight, onSwipeUp, onSwipeDown]);
83
+
84
+ return {
85
+ onTouchStart: handleTouchStart,
86
+ onTouchMove: handleTouchMove,
87
+ onTouchEnd: handleTouchEnd,
88
+ };
89
+ };
90
+
package/src/index.js CHANGED
@@ -1,8 +1,7 @@
1
1
  import React from 'react';
2
2
  import ReactDOM from 'react-dom/client';
3
- import './index.css';
3
+ import './demo.css';
4
4
  import App from './App';
5
- import reportWebVitals from './reportWebVitals';
6
5
 
7
6
  const root = ReactDOM.createRoot(document.getElementById('root'));
8
7
  root.render(
@@ -10,8 +9,3 @@ root.render(
10
9
  <App />
11
10
  </React.StrictMode>
12
11
  );
13
-
14
- // If you want to start measuring performance in your app, pass a function
15
- // to log results (for example: reportWebVitals(console.log))
16
- // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17
- reportWebVitals();
package/src/library.js ADDED
@@ -0,0 +1,26 @@
1
+ import Timeline from "./components/Timeline/Timeline";
2
+ import DailyView from "./components/Timeline/DailyView";
3
+ import ContextMenu from "./components/Timeline/ContextMenu";
4
+ import EventDetailModal from "./components/Timeline/EventDetailModal";
5
+ import EventIcon from "./components/Timeline/EventIcon";
6
+ import EventBadge from "./components/Timeline/EventBadge";
7
+ import LoadingSpinner from "./components/Timeline/LoadingSpinner";
8
+ import AutocompleteSelect from "./components/Timeline/AutocompleteSelect";
9
+
10
+ // Ana Timeline component'i default export
11
+ export default Timeline;
12
+
13
+ // Named exports - İsteğe bağlı kullanım için
14
+ export {
15
+ DailyView,
16
+ ContextMenu,
17
+ EventDetailModal,
18
+ EventIcon,
19
+ EventBadge,
20
+ LoadingSpinner,
21
+ AutocompleteSelect,
22
+ };
23
+
24
+ // CSS dosyası package.json'da exports altında tanımlı
25
+ // Kullanım: import 'akfatimeline/components/Timeline/Timeline.css'
26
+
@@ -0,0 +1,105 @@
1
+ // src/utils/conflictUtils.js
2
+
3
+ import { parseDate } from './dateUtils';
4
+ import { getTimeFromDate } from './timeUtils';
5
+
6
+ /**
7
+ * İki event'in çakışıp çakışmadığını kontrol eder (gün bazlı)
8
+ * @param {Object} event1 - İlk event
9
+ * @param {Object} event2 - İkinci event
10
+ * @returns {boolean} - Çakışma varsa true
11
+ */
12
+ export const checkDayBasedConflict = (event1, event2) => {
13
+ if (event1.resourceId !== event2.resourceId) {
14
+ return false; // Farklı resource'larda çakışma olmaz
15
+ }
16
+
17
+ const start1 = parseDate(event1.startDate);
18
+ const end1 = parseDate(event1.endDate);
19
+ const start2 = parseDate(event2.startDate);
20
+ const end2 = parseDate(event2.endDate);
21
+
22
+ // Çakışma kontrolü: bir event'in başlangıcı diğerinin içinde mi?
23
+ return (start1 <= end2 && end1 >= start2);
24
+ };
25
+
26
+ /**
27
+ * İki event'in saat bazlı çakışıp çakışmadığını kontrol eder
28
+ * @param {Object} event1 - İlk event
29
+ * @param {Object} event2 - İkinci event
30
+ * @returns {boolean} - Çakışma varsa true
31
+ */
32
+ export const checkTimeBasedConflict = (event1, event2) => {
33
+ if (event1.resourceId !== event2.resourceId) {
34
+ return false; // Farklı resource'larda çakışma olmaz
35
+ }
36
+
37
+ const start1 = parseDate(event1.startDate);
38
+ const end1 = parseDate(event1.endDate);
39
+ const start2 = parseDate(event2.startDate);
40
+ const end2 = parseDate(event2.endDate);
41
+
42
+ // Aynı gün mü kontrol et
43
+ if (start1.toDateString() !== start2.toDateString()) {
44
+ return false; // Farklı günlerde çakışma olmaz (günlük kullanım için)
45
+ }
46
+
47
+ // Saat bazlı çakışma kontrolü
48
+ const time1 = getTimeFromDate(start1);
49
+ const time1End = getTimeFromDate(end1);
50
+ const time2 = getTimeFromDate(start2);
51
+ const time2End = getTimeFromDate(end2);
52
+
53
+ return (time1.totalMinutes < time2End.totalMinutes && time1End.totalMinutes > time2.totalMinutes);
54
+ };
55
+
56
+ /**
57
+ * Bir event listesinde çakışmaları bulur
58
+ * @param {Array} events - Event listesi
59
+ * @param {boolean} timeMode - Saat bazlı mod aktif mi
60
+ * @returns {Array} - Çakışma bilgileri [{event1, event2, conflictType}]
61
+ */
62
+ export const detectConflicts = (events, timeMode = false) => {
63
+ const conflicts = [];
64
+ const checkConflict = timeMode ? checkTimeBasedConflict : checkDayBasedConflict;
65
+
66
+ for (let i = 0; i < events.length; i++) {
67
+ for (let j = i + 1; j < events.length; j++) {
68
+ if (checkConflict(events[i], events[j])) {
69
+ conflicts.push({
70
+ event1: events[i],
71
+ event2: events[j],
72
+ conflictType: timeMode ? 'time' : 'day',
73
+ resourceId: events[i].resourceId,
74
+ });
75
+ }
76
+ }
77
+ }
78
+
79
+ return conflicts;
80
+ };
81
+
82
+ /**
83
+ * Belirli bir resource için çakışmaları bulur
84
+ * @param {Array} events - Event listesi
85
+ * @param {string} resourceId - Resource ID
86
+ * @param {boolean} timeMode - Saat bazlı mod aktif mi
87
+ * @returns {Array} - Çakışma bilgileri
88
+ */
89
+ export const detectResourceConflicts = (events, resourceId, timeMode = false) => {
90
+ const resourceEvents = events.filter(e => e.resourceId === resourceId);
91
+ return detectConflicts(resourceEvents, timeMode);
92
+ };
93
+
94
+ /**
95
+ * Bir event'in diğer event'lerle çakışıp çakışmadığını kontrol eder
96
+ * @param {Object} event - Kontrol edilecek event
97
+ * @param {Array} otherEvents - Diğer event'ler
98
+ * @param {boolean} timeMode - Saat bazlı mod aktif mi
99
+ * @returns {Array} - Çakışan event'ler
100
+ */
101
+ export const findEventConflicts = (event, otherEvents, timeMode = false) => {
102
+ const checkConflict = timeMode ? checkTimeBasedConflict : checkDayBasedConflict;
103
+ return otherEvents.filter(e => e.id !== event.id && checkConflict(event, e));
104
+ };
105
+
@@ -1,36 +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
- };
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
+ };
@@ -1,21 +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;
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
21
 
@@ -0,0 +1,106 @@
1
+ // src/utils/filterUtils.js
2
+
3
+ import { parseDate } from './dateUtils';
4
+
5
+ /**
6
+ * Event'leri başlığa göre filtreler
7
+ * @param {Array} events - Event listesi
8
+ * @param {string} searchTerm - Arama terimi
9
+ * @returns {Array} - Filtrelenmiş event listesi
10
+ */
11
+ export const filterByTitle = (events, searchTerm) => {
12
+ if (!searchTerm || searchTerm.trim() === '') {
13
+ return events;
14
+ }
15
+
16
+ const term = searchTerm.toLowerCase().trim();
17
+ return events.filter(event =>
18
+ event.title && event.title.toLowerCase().includes(term)
19
+ );
20
+ };
21
+
22
+ /**
23
+ * Event'leri tarih aralığına göre filtreler
24
+ * @param {Array} events - Event listesi
25
+ * @param {Date} startDate - Başlangıç tarihi
26
+ * @param {Date} endDate - Bitiş tarihi
27
+ * @returns {Array} - Filtrelenmiş event listesi
28
+ */
29
+ export const filterByDateRange = (events, startDate, endDate) => {
30
+ if (!startDate && !endDate) {
31
+ return events;
32
+ }
33
+
34
+ return events.filter(event => {
35
+ const eventStart = parseDate(event.startDate);
36
+ const eventEnd = parseDate(event.endDate);
37
+
38
+ if (startDate && eventEnd < startDate) {
39
+ return false;
40
+ }
41
+ if (endDate && eventStart > endDate) {
42
+ return false;
43
+ }
44
+
45
+ return true;
46
+ });
47
+ };
48
+
49
+ /**
50
+ * Event'leri resource'a göre filtreler
51
+ * @param {Array} events - Event listesi
52
+ * @param {Array} resourceIds - Resource ID listesi
53
+ * @returns {Array} - Filtrelenmiş event listesi
54
+ */
55
+ export const filterByResource = (events, resourceIds) => {
56
+ if (!resourceIds || resourceIds.length === 0) {
57
+ return events;
58
+ }
59
+
60
+ return events.filter(event => resourceIds.includes(event.resourceId));
61
+ };
62
+
63
+ /**
64
+ * Event'leri status'a göre filtreler
65
+ * @param {Array} events - Event listesi
66
+ * @param {Array} statuses - Status listesi
67
+ * @returns {Array} - Filtrelenmiş event listesi
68
+ */
69
+ export const filterByStatus = (events, statuses) => {
70
+ if (!statuses || statuses.length === 0) {
71
+ return events;
72
+ }
73
+
74
+ return events.filter(event =>
75
+ event.status && statuses.includes(event.status)
76
+ );
77
+ };
78
+
79
+ /**
80
+ * Tüm filtreleri uygular
81
+ * @param {Array} events - Event listesi
82
+ * @param {Object} filters - Filtre objesi {searchTerm, startDate, endDate, resourceIds, statuses}
83
+ * @returns {Array} - Filtrelenmiş event listesi
84
+ */
85
+ export const applyFilters = (events, filters) => {
86
+ let filtered = events;
87
+
88
+ if (filters.searchTerm) {
89
+ filtered = filterByTitle(filtered, filters.searchTerm);
90
+ }
91
+
92
+ if (filters.startDate || filters.endDate) {
93
+ filtered = filterByDateRange(filtered, filters.startDate, filters.endDate);
94
+ }
95
+
96
+ if (filters.resourceIds && filters.resourceIds.length > 0) {
97
+ filtered = filterByResource(filtered, filters.resourceIds);
98
+ }
99
+
100
+ if (filters.statuses && filters.statuses.length > 0) {
101
+ filtered = filterByStatus(filtered, filters.statuses);
102
+ }
103
+
104
+ return filtered;
105
+ };
106
+