akfatimeline 2.2.2 → 2.2.3

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/dist/Timeline.js CHANGED
@@ -733,6 +733,23 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/* AkfaTimeline - Glassmorphism Theme
733
733
  box-shadow: var(--shadow-md), 0 0 0 3px var(--accent-light);
734
734
  }
735
735
 
736
+ /* Seçili custom button stili - sadece border parlar, arka plan olmaz */
737
+ .master-header-btn-active {
738
+ background: transparent !important;
739
+ backdrop-filter: none !important;
740
+ -webkit-backdrop-filter: none !important;
741
+ border: 2px solid var(--accent-color, #0ea5e9) !important;
742
+ box-shadow: 0 0 10px rgba(14, 165, 233, 0.5), 0 0 20px rgba(14, 165, 233, 0.3) !important;
743
+ color: var(--text-primary) !important;
744
+ }
745
+
746
+ .master-header-btn-active:hover {
747
+ background: transparent !important;
748
+ border-color: var(--accent-color, #0ea5e9) !important;
749
+ box-shadow: 0 0 15px rgba(14, 165, 233, 0.7), 0 0 25px rgba(14, 165, 233, 0.4) !important;
750
+ transform: translateY(-2px);
751
+ }
752
+
736
753
  .master-header-date-picker {
737
754
  background: var(--bg-secondary);
738
755
  backdrop-filter: var(--blur-sm);
@@ -3161,7 +3178,7 @@ const MasterHeader = _ref => {
3161
3178
  onClick: onToday
3162
3179
  }, "Bug\xFCn")), customButtons && customButtons.length > 0 && customButtons.map(button => /*#__PURE__*/external_react_default().createElement("button", {
3163
3180
  key: button.id,
3164
- className: button.className || "master-header-btn",
3181
+ className: button.className ? "master-header-btn ".concat(button.className) : "master-header-btn",
3165
3182
  onClick: button.onClick,
3166
3183
  disabled: button.disabled,
3167
3184
  title: button.tooltip || button.label
@@ -3358,6 +3375,41 @@ const isDateDisabled = (date, disableDates) => {
3358
3375
  }
3359
3376
  return false;
3360
3377
  };
3378
+
3379
+ /**
3380
+ * Bir tarihin hangi açık range'e ait olduğunu bulur (mode: 'include' için)
3381
+ * @param {string | Object | Date} date - Kontrol edilecek tarih
3382
+ * @param {Object} disableDates - { mode: 'include', dates: [], ranges: [] }
3383
+ * @returns {Object | null} - { start: Date, end: Date } veya null
3384
+ */
3385
+ const findEnabledRangeForDate = (date, disableDates) => {
3386
+ if (!disableDates || !disableDates.mode || disableDates.mode !== 'include') {
3387
+ return null; // Sadece 'include' modu için çalışır
3388
+ }
3389
+ const dateObj = parseDate(date);
3390
+ const dateOnly = new Date(dateObj.getFullYear(), dateObj.getMonth(), dateObj.getDate());
3391
+ const {
3392
+ ranges = []
3393
+ } = disableDates;
3394
+
3395
+ // Tarihin hangi range'e ait olduğunu bul
3396
+ for (const range of ranges) {
3397
+ const start = parseDate(range.start);
3398
+ const end = parseDate(range.end);
3399
+ const startOnly = new Date(start.getFullYear(), start.getMonth(), start.getDate());
3400
+ const endOnly = new Date(end.getFullYear(), end.getMonth(), end.getDate());
3401
+ if (dateOnly >= startOnly && dateOnly <= endOnly) {
3402
+ // Bu range'e ait, range'in tamamını döndür
3403
+ return {
3404
+ start: startOnly,
3405
+ end: endOnly
3406
+ };
3407
+ }
3408
+ }
3409
+
3410
+ // Range bulunamadı, null döndür
3411
+ return null;
3412
+ };
3361
3413
  ;// ./src/components/Timeline/TimelineHeader.jsx
3362
3414
 
3363
3415
  // CSS dosyasını import etmeyi unutma
@@ -4082,38 +4134,79 @@ const TimelineContent = _ref => {
4082
4134
  if (e.button === 2 || e.which === 3) {
4083
4135
  return;
4084
4136
  }
4085
- const startDate = parseDate(date.fullDate);
4137
+ const clickedDate = parseDate(date.fullDate);
4086
4138
 
4087
4139
  // Disabled tarih kontrolü - disabled hücrelerde event oluşturmayı engelle
4088
- if (disableDates && isDateDisabled(startDate, disableDates)) {
4140
+ if (disableDates && isDateDisabled(clickedDate, disableDates)) {
4089
4141
  return;
4090
4142
  }
4091
4143
 
4092
4144
  // Geçmiş tarih kontrolü
4093
4145
  if (preventPastEvents && preventPastEventsDate) {
4094
4146
  const preventPastEventsDateObj = parseDate(preventPastEventsDate);
4095
- // Sadece tarih karşılaştırması (saat bilgisi olmadan)
4096
- const startDateOnly = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
4147
+ const clickedDateOnly = new Date(clickedDate.getFullYear(), clickedDate.getMonth(), clickedDate.getDate());
4097
4148
  const preventPastEventsDateOnly = new Date(preventPastEventsDateObj.getFullYear(), preventPastEventsDateObj.getMonth(), preventPastEventsDateObj.getDate());
4098
- if (startDateOnly < preventPastEventsDateOnly) {
4149
+ if (clickedDateOnly < preventPastEventsDateOnly) {
4099
4150
  // Geçmiş tarihe tıklama engellendi
4100
4151
  return;
4101
4152
  }
4102
4153
  }
4154
+
4155
+ // Eğer disableDates mode: 'include' ise ve ranges varsa, tıklanan tarihin range'ini bul
4156
+ let startDate = clickedDate;
4157
+ let endDate = new Date(clickedDate.getTime() + 24 * 60 * 60 * 1000); // Varsayılan: 1 gün
4158
+ let enabledRange = null;
4159
+ if (disableDates && disableDates.mode === 'include' && disableDates.ranges && disableDates.ranges.length > 0) {
4160
+ enabledRange = findEnabledRangeForDate(clickedDate, disableDates);
4161
+ if (enabledRange) {
4162
+ // Range bulundu, range'in tamamını seç
4163
+ startDate = enabledRange.start;
4164
+ // endDate'i direkt range'in end'i olarak kullan
4165
+ // Range'in end'i zaten son günü temsil ediyor (inclusive)
4166
+ endDate = enabledRange.end;
4167
+ }
4168
+ }
4169
+
4170
+ // Event title'ını gün sayısına göre ayarla
4171
+ const startDateOnly = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
4172
+ const endDateOnly = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
4173
+ // Gün farkını hesapla (gece sayısı = gün farkı)
4174
+ // Örnek: 31 Aralık - 5 Ocak = 5 gece (31-1, 1-2, 2-3, 3-4, 4-5)
4175
+ const daysDiff = Math.round((endDateOnly.getTime() - startDateOnly.getTime()) / (24 * 60 * 60 * 1000));
4176
+ const eventTitle = daysDiff > 0 ? "".concat(daysDiff, " Gece") : "1 Gece";
4177
+
4178
+ // Event'i oluştur - range'in tamamı seçilmiş olacak
4103
4179
  const newEvent = {
4104
4180
  id: Date.now(),
4105
- title: "1 Gece",
4181
+ title: eventTitle,
4106
4182
  startDate,
4107
- endDate: new Date(startDate.getTime() + 24 * 60 * 60 * 1000),
4183
+ endDate,
4108
4184
  resourceId,
4109
- // Mouse başlangıç pozisyonunu kaydet
4185
+ // Mouse başlangıç pozisyonunu kaydet (sürükle-bırak devre dışı olacak)
4110
4186
  startX: (e === null || e === void 0 ? void 0 : e.clientX) || 0,
4111
- startCellIndex: dates.findIndex(d => parseDate(d.fullDate).toDateString() === startDate.toDateString()),
4112
- // color => var(--timeline-new-event-background-color) => => Sonra inline style yerine className
4113
- color: "" // Bunu .css'te "var(--timeline-new-event-background-color)" atayabilirsin
4187
+ startCellIndex: dates.findIndex(d => {
4188
+ const dDate = parseDate(d.fullDate);
4189
+ const dDateOnly = new Date(dDate.getFullYear(), dDate.getMonth(), dDate.getDate());
4190
+ const startDateOnlyCheck = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
4191
+ return dDateOnly.getTime() === startDateOnlyCheck.getTime();
4192
+ }),
4193
+ color: ""
4114
4194
  };
4115
- setTempEvent(newEvent);
4116
- setIsCreating(true);
4195
+
4196
+ // Event'i direkt oluştur (sürükle-bırak olmadan)
4197
+ if (enabledRange) {
4198
+ // Range seçildi, direkt event oluştur (sürükle-bırak devre dışı)
4199
+ setEvents(prev => [...prev, newEvent]);
4200
+
4201
+ // Callback'i çağır
4202
+ if (onCreateEventInfo) {
4203
+ onCreateEventInfo(newEvent);
4204
+ }
4205
+ } else {
4206
+ // Range bulunamadı, eski davranış (sürükle-bırak ile seçim)
4207
+ setTempEvent(newEvent);
4208
+ setIsCreating(true);
4209
+ }
4117
4210
  };
4118
4211
  (0,external_react_.useEffect)(() => {
4119
4212
  if (!createNewEventOn) return;
@@ -66,7 +66,7 @@ const MasterHeader = ({
66
66
  {customButtons && customButtons.length > 0 && customButtons.map((button) => (
67
67
  <button
68
68
  key={button.id}
69
- className={button.className || "master-header-btn"}
69
+ className={button.className ? `master-header-btn ${button.className}` : "master-header-btn"}
70
70
  onClick={button.onClick}
71
71
  disabled={button.disabled}
72
72
  title={button.tooltip || button.label}
@@ -704,6 +704,23 @@
704
704
  box-shadow: var(--shadow-md), 0 0 0 3px var(--accent-light);
705
705
  }
706
706
 
707
+ /* Seçili custom button stili - sadece border parlar, arka plan olmaz */
708
+ .master-header-btn-active {
709
+ background: transparent !important;
710
+ backdrop-filter: none !important;
711
+ -webkit-backdrop-filter: none !important;
712
+ border: 2px solid var(--accent-color, #0ea5e9) !important;
713
+ box-shadow: 0 0 10px rgba(14, 165, 233, 0.5), 0 0 20px rgba(14, 165, 233, 0.3) !important;
714
+ color: var(--text-primary) !important;
715
+ }
716
+
717
+ .master-header-btn-active:hover {
718
+ background: transparent !important;
719
+ border-color: var(--accent-color, #0ea5e9) !important;
720
+ box-shadow: 0 0 15px rgba(14, 165, 233, 0.7), 0 0 25px rgba(14, 165, 233, 0.4) !important;
721
+ transform: translateY(-2px);
722
+ }
723
+
707
724
  .master-header-date-picker {
708
725
  background: var(--bg-secondary);
709
726
  backdrop-filter: var(--blur-sm);
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useRef, useEffect, useCallback } from "react";
2
- import { parseDate, isDateDisabled } from "../../utils/dateUtils";
2
+ import { parseDate, isDateDisabled, findEnabledRangeForDate } from "../../utils/dateUtils";
3
3
  import useDragAndDrop from "../../hooks/useDragAndDrop";
4
4
  import useEventDragDrop from "../../hooks/useEventDragDrop";
5
5
  import Indicator from "./Indicator.jsx";
@@ -202,40 +202,81 @@ const TimelineContent = ({
202
202
  return;
203
203
  }
204
204
 
205
- const startDate = parseDate(date.fullDate);
205
+ const clickedDate = parseDate(date.fullDate);
206
206
 
207
207
  // Disabled tarih kontrolü - disabled hücrelerde event oluşturmayı engelle
208
- if (disableDates && isDateDisabled(startDate, disableDates)) {
208
+ if (disableDates && isDateDisabled(clickedDate, disableDates)) {
209
209
  return;
210
210
  }
211
211
 
212
212
  // Geçmiş tarih kontrolü
213
213
  if (preventPastEvents && preventPastEventsDate) {
214
214
  const preventPastEventsDateObj = parseDate(preventPastEventsDate);
215
- // Sadece tarih karşılaştırması (saat bilgisi olmadan)
216
- const startDateOnly = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
215
+ const clickedDateOnly = new Date(clickedDate.getFullYear(), clickedDate.getMonth(), clickedDate.getDate());
217
216
  const preventPastEventsDateOnly = new Date(preventPastEventsDateObj.getFullYear(), preventPastEventsDateObj.getMonth(), preventPastEventsDateObj.getDate());
218
217
 
219
- if (startDateOnly < preventPastEventsDateOnly) {
218
+ if (clickedDateOnly < preventPastEventsDateOnly) {
220
219
  // Geçmiş tarihe tıklama engellendi
221
220
  return;
222
221
  }
223
222
  }
224
223
 
224
+ // Eğer disableDates mode: 'include' ise ve ranges varsa, tıklanan tarihin range'ini bul
225
+ let startDate = clickedDate;
226
+ let endDate = new Date(clickedDate.getTime() + 24 * 60 * 60 * 1000); // Varsayılan: 1 gün
227
+ let enabledRange = null;
228
+
229
+ if (disableDates && disableDates.mode === 'include' && disableDates.ranges && disableDates.ranges.length > 0) {
230
+ enabledRange = findEnabledRangeForDate(clickedDate, disableDates);
231
+ if (enabledRange) {
232
+ // Range bulundu, range'in tamamını seç
233
+ startDate = enabledRange.start;
234
+ // endDate'i direkt range'in end'i olarak kullan
235
+ // Range'in end'i zaten son günü temsil ediyor (inclusive)
236
+ endDate = enabledRange.end;
237
+ }
238
+ }
239
+
240
+ // Event title'ını gün sayısına göre ayarla
241
+ const startDateOnly = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
242
+ const endDateOnly = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
243
+ // Gün farkını hesapla (gece sayısı = gün farkı)
244
+ // Örnek: 31 Aralık - 5 Ocak = 5 gece (31-1, 1-2, 2-3, 3-4, 4-5)
245
+ const daysDiff = Math.round((endDateOnly.getTime() - startDateOnly.getTime()) / (24 * 60 * 60 * 1000));
246
+ const eventTitle = daysDiff > 0 ? `${daysDiff} Gece` : "1 Gece";
247
+
248
+ // Event'i oluştur - range'in tamamı seçilmiş olacak
225
249
  const newEvent = {
226
250
  id: Date.now(),
227
- title: "1 Gece",
251
+ title: eventTitle,
228
252
  startDate,
229
- endDate: new Date(startDate.getTime() + 24 * 60 * 60 * 1000),
253
+ endDate,
230
254
  resourceId,
231
- // Mouse başlangıç pozisyonunu kaydet
255
+ // Mouse başlangıç pozisyonunu kaydet (sürükle-bırak devre dışı olacak)
232
256
  startX: e?.clientX || 0,
233
- startCellIndex: dates.findIndex((d) => parseDate(d.fullDate).toDateString() === startDate.toDateString()),
234
- // color => var(--timeline-new-event-background-color) => => Sonra inline style yerine className
235
- color: "", // Bunu .css'te "var(--timeline-new-event-background-color)" atayabilirsin
257
+ startCellIndex: dates.findIndex((d) => {
258
+ const dDate = parseDate(d.fullDate);
259
+ const dDateOnly = new Date(dDate.getFullYear(), dDate.getMonth(), dDate.getDate());
260
+ const startDateOnlyCheck = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
261
+ return dDateOnly.getTime() === startDateOnlyCheck.getTime();
262
+ }),
263
+ color: "",
236
264
  };
237
- setTempEvent(newEvent);
238
- setIsCreating(true);
265
+
266
+ // Event'i direkt oluştur (sürükle-bırak olmadan)
267
+ if (enabledRange) {
268
+ // Range seçildi, direkt event oluştur (sürükle-bırak devre dışı)
269
+ setEvents((prev) => [...prev, newEvent]);
270
+
271
+ // Callback'i çağır
272
+ if (onCreateEventInfo) {
273
+ onCreateEventInfo(newEvent);
274
+ }
275
+ } else {
276
+ // Range bulunamadı, eski davranış (sürükle-bırak ile seçim)
277
+ setTempEvent(newEvent);
278
+ setIsCreating(true);
279
+ }
239
280
  };
240
281
 
241
282
  useEffect(() => {
@@ -95,3 +95,39 @@ export const isDateDisabled = (date, disableDates) => {
95
95
 
96
96
  return false;
97
97
  };
98
+
99
+ /**
100
+ * Bir tarihin hangi açık range'e ait olduğunu bulur (mode: 'include' için)
101
+ * @param {string | Object | Date} date - Kontrol edilecek tarih
102
+ * @param {Object} disableDates - { mode: 'include', dates: [], ranges: [] }
103
+ * @returns {Object | null} - { start: Date, end: Date } veya null
104
+ */
105
+ export const findEnabledRangeForDate = (date, disableDates) => {
106
+ if (!disableDates || !disableDates.mode || disableDates.mode !== 'include') {
107
+ return null; // Sadece 'include' modu için çalışır
108
+ }
109
+
110
+ const dateObj = parseDate(date);
111
+ const dateOnly = new Date(dateObj.getFullYear(), dateObj.getMonth(), dateObj.getDate());
112
+
113
+ const { ranges = [] } = disableDates;
114
+
115
+ // Tarihin hangi range'e ait olduğunu bul
116
+ for (const range of ranges) {
117
+ const start = parseDate(range.start);
118
+ const end = parseDate(range.end);
119
+ const startOnly = new Date(start.getFullYear(), start.getMonth(), start.getDate());
120
+ const endOnly = new Date(end.getFullYear(), end.getMonth(), end.getDate());
121
+
122
+ if (dateOnly >= startOnly && dateOnly <= endOnly) {
123
+ // Bu range'e ait, range'in tamamını döndür
124
+ return {
125
+ start: startOnly,
126
+ end: endOnly,
127
+ };
128
+ }
129
+ }
130
+
131
+ // Range bulunamadı, null döndür
132
+ return null;
133
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akfatimeline",
3
- "version": "2.2.2",
3
+ "version": "2.2.3",
4
4
  "description": "A customizable timeline component for React applications with disableDates, custom header buttons, and past date protection features",
5
5
  "main": "./src/library.js",
6
6
  "module": "./src/library.js",
package/src/App.js CHANGED
@@ -9,10 +9,10 @@ const App = () => {
9
9
  const todayDate = new Date(today.getFullYear(), today.getMonth(), today.getDate());
10
10
 
11
11
  // Timeline'ın gösterileceği tarih state'i
12
+ // Test için 31 Aralık 2025 civarına ayarladık (disable dates testi için)
12
13
  const [programDate, setProgramDate] = useState(() => {
13
- const date = new Date();
14
- date.setDate(date.getDate() - 3); // 3 gün öncesinden başla
15
- return date.toISOString().split('T')[0]; // YYYY-MM-DD formatı
14
+ // Test için 31 Aralık 2025'ten 3 gün öncesinden başla (28 Aralık)
15
+ return '2025-12-28'; // YYYY-MM-DD formatı
16
16
  });
17
17
 
18
18
  // Geçmiş tarih koruması için minimum tarih (programDate ve indicatorDate'ten bağımsız)
@@ -42,8 +42,18 @@ const App = () => {
42
42
  // Loading State
43
43
  const [isLoading, setIsLoading] = useState(false);
44
44
 
45
- // Disable Dates kaldırıldı - Tüm tarihler açık
46
- const disableDates = null;
45
+ // Disable Dates - Test için: 31 Aralık - 5 Ocak arası açık, geri kalan her yer disabled
46
+ // mode: 'include' = belirtilen tarihler ve aralıklar enabled (diğerleri disabled)
47
+ const disableDates = {
48
+ mode: 'include', // Belirtilen tarihler ve aralıklar enabled, diğerleri disabled
49
+ dates: [], // Tekil tarihler (şimdilik boş)
50
+ ranges: [
51
+ {
52
+ start: '2025-12-31', // 31 Aralık 2025
53
+ end: '2026-01-05', // 5 Ocak 2026
54
+ },
55
+ ],
56
+ };
47
57
 
48
58
  // Cell Tooltip için örnek fiyat verisi
49
59
  // Her gün için farklı fiyatlar tanımlanabilir
@@ -66,7 +66,7 @@ const MasterHeader = ({
66
66
  {customButtons && customButtons.length > 0 && customButtons.map((button) => (
67
67
  <button
68
68
  key={button.id}
69
- className={button.className || "master-header-btn"}
69
+ className={button.className ? `master-header-btn ${button.className}` : "master-header-btn"}
70
70
  onClick={button.onClick}
71
71
  disabled={button.disabled}
72
72
  title={button.tooltip || button.label}
@@ -704,6 +704,23 @@
704
704
  box-shadow: var(--shadow-md), 0 0 0 3px var(--accent-light);
705
705
  }
706
706
 
707
+ /* Seçili custom button stili - sadece border parlar, arka plan olmaz */
708
+ .master-header-btn-active {
709
+ background: transparent !important;
710
+ backdrop-filter: none !important;
711
+ -webkit-backdrop-filter: none !important;
712
+ border: 2px solid var(--accent-color, #0ea5e9) !important;
713
+ box-shadow: 0 0 10px rgba(14, 165, 233, 0.5), 0 0 20px rgba(14, 165, 233, 0.3) !important;
714
+ color: var(--text-primary) !important;
715
+ }
716
+
717
+ .master-header-btn-active:hover {
718
+ background: transparent !important;
719
+ border-color: var(--accent-color, #0ea5e9) !important;
720
+ box-shadow: 0 0 15px rgba(14, 165, 233, 0.7), 0 0 25px rgba(14, 165, 233, 0.4) !important;
721
+ transform: translateY(-2px);
722
+ }
723
+
707
724
  .master-header-date-picker {
708
725
  background: var(--bg-secondary);
709
726
  backdrop-filter: var(--blur-sm);
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useRef, useEffect, useCallback } from "react";
2
- import { parseDate, isDateDisabled } from "../../utils/dateUtils";
2
+ import { parseDate, isDateDisabled, findEnabledRangeForDate } from "../../utils/dateUtils";
3
3
  import useDragAndDrop from "../../hooks/useDragAndDrop";
4
4
  import useEventDragDrop from "../../hooks/useEventDragDrop";
5
5
  import Indicator from "./Indicator.jsx";
@@ -202,40 +202,81 @@ const TimelineContent = ({
202
202
  return;
203
203
  }
204
204
 
205
- const startDate = parseDate(date.fullDate);
205
+ const clickedDate = parseDate(date.fullDate);
206
206
 
207
207
  // Disabled tarih kontrolü - disabled hücrelerde event oluşturmayı engelle
208
- if (disableDates && isDateDisabled(startDate, disableDates)) {
208
+ if (disableDates && isDateDisabled(clickedDate, disableDates)) {
209
209
  return;
210
210
  }
211
211
 
212
212
  // Geçmiş tarih kontrolü
213
213
  if (preventPastEvents && preventPastEventsDate) {
214
214
  const preventPastEventsDateObj = parseDate(preventPastEventsDate);
215
- // Sadece tarih karşılaştırması (saat bilgisi olmadan)
216
- const startDateOnly = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
215
+ const clickedDateOnly = new Date(clickedDate.getFullYear(), clickedDate.getMonth(), clickedDate.getDate());
217
216
  const preventPastEventsDateOnly = new Date(preventPastEventsDateObj.getFullYear(), preventPastEventsDateObj.getMonth(), preventPastEventsDateObj.getDate());
218
217
 
219
- if (startDateOnly < preventPastEventsDateOnly) {
218
+ if (clickedDateOnly < preventPastEventsDateOnly) {
220
219
  // Geçmiş tarihe tıklama engellendi
221
220
  return;
222
221
  }
223
222
  }
224
223
 
224
+ // Eğer disableDates mode: 'include' ise ve ranges varsa, tıklanan tarihin range'ini bul
225
+ let startDate = clickedDate;
226
+ let endDate = new Date(clickedDate.getTime() + 24 * 60 * 60 * 1000); // Varsayılan: 1 gün
227
+ let enabledRange = null;
228
+
229
+ if (disableDates && disableDates.mode === 'include' && disableDates.ranges && disableDates.ranges.length > 0) {
230
+ enabledRange = findEnabledRangeForDate(clickedDate, disableDates);
231
+ if (enabledRange) {
232
+ // Range bulundu, range'in tamamını seç
233
+ startDate = enabledRange.start;
234
+ // endDate'i direkt range'in end'i olarak kullan
235
+ // Range'in end'i zaten son günü temsil ediyor (inclusive)
236
+ endDate = enabledRange.end;
237
+ }
238
+ }
239
+
240
+ // Event title'ını gün sayısına göre ayarla
241
+ const startDateOnly = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
242
+ const endDateOnly = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
243
+ // Gün farkını hesapla (gece sayısı = gün farkı)
244
+ // Örnek: 31 Aralık - 5 Ocak = 5 gece (31-1, 1-2, 2-3, 3-4, 4-5)
245
+ const daysDiff = Math.round((endDateOnly.getTime() - startDateOnly.getTime()) / (24 * 60 * 60 * 1000));
246
+ const eventTitle = daysDiff > 0 ? `${daysDiff} Gece` : "1 Gece";
247
+
248
+ // Event'i oluştur - range'in tamamı seçilmiş olacak
225
249
  const newEvent = {
226
250
  id: Date.now(),
227
- title: "1 Gece",
251
+ title: eventTitle,
228
252
  startDate,
229
- endDate: new Date(startDate.getTime() + 24 * 60 * 60 * 1000),
253
+ endDate,
230
254
  resourceId,
231
- // Mouse başlangıç pozisyonunu kaydet
255
+ // Mouse başlangıç pozisyonunu kaydet (sürükle-bırak devre dışı olacak)
232
256
  startX: e?.clientX || 0,
233
- startCellIndex: dates.findIndex((d) => parseDate(d.fullDate).toDateString() === startDate.toDateString()),
234
- // color => var(--timeline-new-event-background-color) => => Sonra inline style yerine className
235
- color: "", // Bunu .css'te "var(--timeline-new-event-background-color)" atayabilirsin
257
+ startCellIndex: dates.findIndex((d) => {
258
+ const dDate = parseDate(d.fullDate);
259
+ const dDateOnly = new Date(dDate.getFullYear(), dDate.getMonth(), dDate.getDate());
260
+ const startDateOnlyCheck = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
261
+ return dDateOnly.getTime() === startDateOnlyCheck.getTime();
262
+ }),
263
+ color: "",
236
264
  };
237
- setTempEvent(newEvent);
238
- setIsCreating(true);
265
+
266
+ // Event'i direkt oluştur (sürükle-bırak olmadan)
267
+ if (enabledRange) {
268
+ // Range seçildi, direkt event oluştur (sürükle-bırak devre dışı)
269
+ setEvents((prev) => [...prev, newEvent]);
270
+
271
+ // Callback'i çağır
272
+ if (onCreateEventInfo) {
273
+ onCreateEventInfo(newEvent);
274
+ }
275
+ } else {
276
+ // Range bulunamadı, eski davranış (sürükle-bırak ile seçim)
277
+ setTempEvent(newEvent);
278
+ setIsCreating(true);
279
+ }
239
280
  };
240
281
 
241
282
  useEffect(() => {
@@ -95,3 +95,39 @@ export const isDateDisabled = (date, disableDates) => {
95
95
 
96
96
  return false;
97
97
  };
98
+
99
+ /**
100
+ * Bir tarihin hangi açık range'e ait olduğunu bulur (mode: 'include' için)
101
+ * @param {string | Object | Date} date - Kontrol edilecek tarih
102
+ * @param {Object} disableDates - { mode: 'include', dates: [], ranges: [] }
103
+ * @returns {Object | null} - { start: Date, end: Date } veya null
104
+ */
105
+ export const findEnabledRangeForDate = (date, disableDates) => {
106
+ if (!disableDates || !disableDates.mode || disableDates.mode !== 'include') {
107
+ return null; // Sadece 'include' modu için çalışır
108
+ }
109
+
110
+ const dateObj = parseDate(date);
111
+ const dateOnly = new Date(dateObj.getFullYear(), dateObj.getMonth(), dateObj.getDate());
112
+
113
+ const { ranges = [] } = disableDates;
114
+
115
+ // Tarihin hangi range'e ait olduğunu bul
116
+ for (const range of ranges) {
117
+ const start = parseDate(range.start);
118
+ const end = parseDate(range.end);
119
+ const startOnly = new Date(start.getFullYear(), start.getMonth(), start.getDate());
120
+ const endOnly = new Date(end.getFullYear(), end.getMonth(), end.getDate());
121
+
122
+ if (dateOnly >= startOnly && dateOnly <= endOnly) {
123
+ // Bu range'e ait, range'in tamamını döndür
124
+ return {
125
+ start: startOnly,
126
+ end: endOnly,
127
+ };
128
+ }
129
+ }
130
+
131
+ // Range bulunamadı, null döndür
132
+ return null;
133
+ };