feat: first version of the interface, integrate Tailwind CSS and update routing

- Add Tailwind CSS dependencies and configure Vite to use Tailwind
- Implement routing with React Router for Landing and Dashboard pages
- Remove unused App.css file and refactor App component to utilize new structure
- Update global styles in index.css to incorporate Tailwind's utility classes
This commit is contained in:
Alexis
2026-04-23 09:49:38 +02:00
parent 4627d160e8
commit a07bd3146e
26 changed files with 1819 additions and 460 deletions
+28
View File
@@ -0,0 +1,28 @@
/**
* Locale-aware full date + time formatter (used in dashboard headers).
*/
export function formatDate(iso) {
if (!iso) return "—";
const d = new Date(iso);
if (Number.isNaN(d.getTime())) return "—";
return d.toLocaleString("es-ES", {
day: "2-digit",
month: "long",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
});
}
/**
* Builds researcher initials (max 2 chars) from a full name.
*/
export function getInitials(name = "") {
return name
.trim()
.split(/\s+/)
.map((w) => w[0] ?? "")
.slice(0, 2)
.join("")
.toUpperCase();
}
+22
View File
@@ -0,0 +1,22 @@
/**
* ORCID iD regex (16 digits, hyphen every 4, last char may be 'X' checksum).
* @see https://support.orcid.org/hc/en-us/articles/360006897674
*/
export const ORCID_REGEX = /^\d{4}-\d{4}-\d{4}-\d{3}[\dX]$/;
/**
* Auto-formats a raw user input into the canonical ORCID layout
* `0000-0000-0000-000X`, keeping digits + final 'X' only.
*/
export function formatOrcidInput(raw) {
const digits = raw.replace(/[^0-9X]/gi, "").toUpperCase();
const parts = [];
for (let i = 0; i < digits.length && i < 16; i += 4) {
parts.push(digits.slice(i, i + 4));
}
return parts.join("-");
}
export function isValidOrcid(value) {
return ORCID_REGEX.test(value);
}
+28
View File
@@ -0,0 +1,28 @@
/**
* Publication type catalogue — labels + Tailwind class sets per variant.
* Keeping Tailwind classes (instead of inline styles) here lets the Badge
* component stay declarative while still covering every ORCID work-type.
*/
export const TYPE_LABELS = {
"journal-article": "Artículo",
review: "Revisión",
"conference-paper": "Conferencia",
"book-chapter": "Cap. Libro",
dataset: "Dataset",
};
export const TYPE_BADGE_CLASSES = {
"journal-article":
"bg-tag-article-bg text-tag-article-text border border-tag-article-border",
review:
"bg-tag-review-bg text-tag-review-text border border-tag-review-border",
"conference-paper":
"bg-tag-conference-bg text-tag-conference-text border border-tag-conference-border",
"book-chapter":
"bg-tag-book-bg text-tag-book-text border border-tag-book-border",
dataset:
"bg-tag-dataset-bg text-tag-dataset-text border border-tag-dataset-border",
};
export const DEFAULT_BADGE_CLASSES =
"bg-tag-default-bg text-tag-default-text border border-tag-default-border";