feat: enhance date parsing to support month-only formats and normalize URLs to prevent duplicates
This commit is contained in:
31
src/App.jsx
31
src/App.jsx
@@ -31,8 +31,37 @@ const DATE_RANGE_OPTIONS = [
|
|||||||
|
|
||||||
const parseDate = (value) => {
|
const parseDate = (value) => {
|
||||||
if (!value) return null;
|
if (!value) return null;
|
||||||
const date = new Date(value);
|
|
||||||
|
const toDate = (input) => {
|
||||||
|
const date = new Date(input);
|
||||||
return Number.isNaN(date.getTime()) ? null : date;
|
return Number.isNaN(date.getTime()) ? null : date;
|
||||||
|
};
|
||||||
|
|
||||||
|
let date = value instanceof Date ? value : null;
|
||||||
|
|
||||||
|
if (!date && (typeof value === "number" || typeof value === "string")) {
|
||||||
|
date = toDate(value);
|
||||||
|
|
||||||
|
if (!date && typeof value === "string") {
|
||||||
|
const trimmed = value.trim();
|
||||||
|
const dayMatch = trimmed.match(/^([0-9]{1,2})[\/\-]([0-9]{1,2})[\/\-]([0-9]{2,4})$/);
|
||||||
|
|
||||||
|
if (dayMatch) {
|
||||||
|
const [, day, month, year] = dayMatch;
|
||||||
|
const normalizedYear = year.length === 2 ? `20${year}` : year;
|
||||||
|
date = toDate(`${normalizedYear.padStart(4, "0")}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`);
|
||||||
|
} else {
|
||||||
|
const monthMatch = trimmed.match(/^([0-9]{1,2})[\/\-]([0-9]{2,4})$/);
|
||||||
|
if (monthMatch) {
|
||||||
|
const [, month, year] = monthMatch;
|
||||||
|
const normalizedYear = year.length === 2 ? `20${year}` : year;
|
||||||
|
date = toDate(`${normalizedYear.padStart(4, "0")}-${month.padStart(2, "0")}-01`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return date;
|
||||||
};
|
};
|
||||||
|
|
||||||
const matchesDateRange = (annonce, range) => {
|
const matchesDateRange = (annonce, range) => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { X, Plus, Loader2, Link } from "lucide-react";
|
import { X, Plus, Loader2, Link } from "lucide-react";
|
||||||
|
|
||||||
export default function AddModal({ open, onClose, onSubmit, existingUrls }) {
|
export default function AddModal({ open, onClose, onSubmit, existingUrls }) {
|
||||||
@@ -6,11 +6,29 @@ export default function AddModal({ open, onClose, onSubmit, existingUrls }) {
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [urlError, setUrlError] = useState("");
|
const [urlError, setUrlError] = useState("");
|
||||||
|
|
||||||
|
const normalizeUrl = (raw) => {
|
||||||
|
if (!raw) return "";
|
||||||
|
try {
|
||||||
|
const parsed = new URL(raw.trim());
|
||||||
|
parsed.hash = "";
|
||||||
|
parsed.search = "";
|
||||||
|
return `${parsed.origin}${parsed.pathname}`;
|
||||||
|
} catch (err) {
|
||||||
|
return raw.trim().split(/[?#]/)[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const normalizedExisting = useMemo(
|
||||||
|
() => existingUrls.map((item) => normalizeUrl(item)),
|
||||||
|
[existingUrls]
|
||||||
|
);
|
||||||
|
|
||||||
if (!open) return null;
|
if (!open) return null;
|
||||||
|
|
||||||
const handleUrlChange = (val) => {
|
const handleUrlChange = (val) => {
|
||||||
setUrl(val);
|
setUrl(val);
|
||||||
if (existingUrls.includes(val.trim())) {
|
const normalized = normalizeUrl(val);
|
||||||
|
if (normalized && normalizedExisting.includes(normalized)) {
|
||||||
setUrlError("Cette URL existe deja dans la liste !");
|
setUrlError("Cette URL existe deja dans la liste !");
|
||||||
} else {
|
} else {
|
||||||
setUrlError("");
|
setUrlError("");
|
||||||
|
|||||||
@@ -65,12 +65,20 @@ const formatFrDate = (value) => {
|
|||||||
date = toDate(value);
|
date = toDate(value);
|
||||||
|
|
||||||
if (!date && typeof value === "string") {
|
if (!date && typeof value === "string") {
|
||||||
const match = value.trim().match(/^([0-9]{1,2})[\/\-]([0-9]{1,2})[\/\-]([0-9]{2,4})$/);
|
const trimmed = value.trim();
|
||||||
|
const dayMatch = trimmed.match(/^([0-9]{1,2})[\/\-]([0-9]{1,2})[\/\-]([0-9]{2,4})$/);
|
||||||
|
|
||||||
if (match) {
|
if (dayMatch) {
|
||||||
const [, day, month, year] = match;
|
const [, day, month, year] = dayMatch;
|
||||||
const normalizedYear = year.length === 2 ? `20${year}` : year;
|
const normalizedYear = year.length === 2 ? `20${year}` : year;
|
||||||
date = toDate(`${normalizedYear.padStart(4, "0")}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`);
|
date = toDate(`${normalizedYear.padStart(4, "0")}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`);
|
||||||
|
} else {
|
||||||
|
const monthMatch = trimmed.match(/^([0-9]{1,2})[\/\-]([0-9]{2,4})$/);
|
||||||
|
if (monthMatch) {
|
||||||
|
const [, month, year] = monthMatch;
|
||||||
|
const normalizedYear = year.length === 2 ? `20${year}` : year;
|
||||||
|
date = toDate(`${normalizedYear.padStart(4, "0")}-${month.padStart(2, "0")}-01`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user