diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx
index 3b0c119..1fc4992 100644
--- a/src/app/admin/page.tsx
+++ b/src/app/admin/page.tsx
@@ -160,7 +160,7 @@ export default function AdminPage() {
"projects.json": { name: "", description: "", link: "", open_source: false },
"mini_projects.json": { title: "", description: "", why: "" },
"experience.json": { name: "", type: "experience", description: "" },
- "real_work.json": { company: "", summary: "" }
+ "real_work.json": { company: "", role: "", from: "", until: "", summary: "" }
};
setData([templates[selectedFile], ...data]);
};
@@ -333,6 +333,18 @@ export default function AdminPage() {
updateEntry(idx, "company", e.target.value)} className="w-full bg-black/40 border border-white/10 rounded-lg p-2 text-sm" />
+
+
+ updateEntry(idx, "role", e.target.value)} className="w-full bg-black/40 border border-white/10 rounded-lg p-2 text-sm" />
+
+
+
+ updateEntry(idx, "from", e.target.value)} className="w-full bg-black/40 border border-white/10 rounded-lg p-2 text-sm" placeholder="YYYY-MM" />
+
+
+
+ updateEntry(idx, "until", e.target.value)} className="w-full bg-black/40 border border-white/10 rounded-lg p-2 text-sm" placeholder="YYYY-MM or Present" />
+
updateEntry(idx, "url", e.target.value)} className="w-full bg-black/40 border border-white/10 rounded-lg p-2 text-sm" />
diff --git a/src/sections/WorkExperience.tsx b/src/sections/WorkExperience.tsx
index 6150f56..117c42f 100644
--- a/src/sections/WorkExperience.tsx
+++ b/src/sections/WorkExperience.tsx
@@ -6,7 +6,50 @@ interface WorkExperienceProps {
realWork: RealWork[];
}
+function getWorkDateTimestamp(dateValue?: string) {
+ if (!dateValue) return Number.NEGATIVE_INFINITY;
+ const timestamp = Date.parse(dateValue);
+ return Number.isNaN(timestamp) ? Number.NEGATIVE_INFINITY : timestamp;
+}
+
+function getSortTimestamp(entry: RealWork) {
+ if (!entry.until || entry.until.trim().toLowerCase() === "present") {
+ return Number.POSITIVE_INFINITY;
+ }
+ const untilTimestamp = getWorkDateTimestamp(entry.until);
+ if (untilTimestamp !== Number.NEGATIVE_INFINITY) return untilTimestamp;
+ return getWorkDateTimestamp(entry.from);
+}
+
+function formatWorkDate(dateValue: string) {
+ const yearMonthMatch = /^(\d{4})-(\d{2})$/.exec(dateValue.trim());
+ if (yearMonthMatch) {
+ const year = Number.parseInt(yearMonthMatch[1], 10);
+ const monthIndex = Number.parseInt(yearMonthMatch[2], 10) - 1;
+ if (monthIndex >= 0 && monthIndex <= 11) {
+ return new Date(Date.UTC(year, monthIndex, 1)).toLocaleDateString("en-US", {
+ year: "numeric",
+ month: "short",
+ timeZone: "UTC",
+ });
+ }
+ }
+
+ const timestamp = Date.parse(dateValue);
+ if (Number.isNaN(timestamp)) return dateValue;
+ return new Date(timestamp).toLocaleDateString("en-US", {
+ year: "numeric",
+ month: "short",
+ });
+}
+
export function WorkExperience({ realWork }: WorkExperienceProps) {
+ const sortedRealWork = [...realWork].sort(
+ (a, b) =>
+ getSortTimestamp(b) - getSortTimestamp(a) ||
+ getWorkDateTimestamp(b.from) - getWorkDateTimestamp(a.from),
+ );
+
return (
@@ -24,13 +67,28 @@ export function WorkExperience({ realWork }: WorkExperienceProps) {
) : (
- {realWork.map((entry, index) => (
+ {sortedRealWork.map((entry, index) => (
-
{entry.company}
+
+
{entry.company}
+ {entry.role ? (
+
{entry.role}
+ ) : null}
+ {entry.from || entry.until ? (
+
+ {entry.from ? formatWorkDate(entry.from) : "Unknown"} -{" "}
+ {entry.until
+ ? entry.until.trim().toLowerCase() === "present"
+ ? "Present"
+ : formatWorkDate(entry.until)
+ : "Present"}
+
+ ) : null}
+
{entry.url ? (