unipo-ui 1.7.0 → 1.8.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.
@@ -1,12 +1,13 @@
1
1
  'use client';
2
2
  import { parseISODate, toISODate, monthMatrix } from './chunk-5T2FWP5A.js';
3
- import { Button, Skeleton, Accordion, Empty, formatTime, Tooltip, formatCompact, formatDate, Menu as Menu$1, Avatar, Dialog, formatRelative } from './chunk-OLQKRLWL.js';
3
+ import { Button, Skeleton, Accordion, Empty, Avatar, formatTime, Tooltip, formatCompact, formatDate, Menu as Menu$2, Dialog, formatRelative } from './chunk-OLQKRLWL.js';
4
4
  import { dataFlag, cn } from './chunk-JSUHAYQ4.js';
5
5
  import * as React from 'react';
6
6
  import { NavigationMenu } from '@base-ui/react/navigation-menu';
7
7
  import { Collapsible } from '@base-ui/react/collapsible';
8
- import { ChevronDown, Menu, SearchX, MessageCircleQuestion, Clock, RefreshCw, ChevronLeft, ChevronRight, CalendarDays, Eye, Pin, Megaphone, ArrowUpRight, Video, MapPin, Users, ArrowRight, Search, Loader2, XCircle, Wrench, AlertTriangle, CheckCircle2 } from 'lucide-react';
8
+ import { ChevronDown, Menu, SearchX, MessageCircleQuestion, UserRound, ChevronsUpDown, Users, Check, Sun, Moon, Monitor, LogOut, PenLine, ShieldCheck, Clock, RefreshCw, ChevronLeft, ChevronRight, CalendarDays, Eye, Pin, Megaphone, ArrowUpRight, Video, MapPin, ArrowRight, Search, KeyRound, IdCard, Loader2, XCircle, Wrench, AlertTriangle, CheckCircle2 } from 'lucide-react';
9
9
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
10
+ import { Menu as Menu$1 } from '@base-ui/react/menu';
10
11
 
11
12
  function useScrolled(on, threshold = 8) {
12
13
  const [s, setS] = React.useState(false);
@@ -109,7 +110,7 @@ function Panel({ menu, renderLink }) {
109
110
  }
110
111
  function UserMenu({ user }) {
111
112
  return /* @__PURE__ */ jsx(
112
- Menu$1,
113
+ Menu$2,
113
114
  {
114
115
  align: "end",
115
116
  trigger: /* @__PURE__ */ jsxs("button", { type: "button", className: "u-navbar-user", "aria-label": `Menu ${user.name}`, children: [
@@ -539,6 +540,200 @@ function LogoAplikasi({ kode, name, src, ssoUrl = "https://sso.unipo.ac.id", tag
539
540
  const layout = props.layout === "full" ? "horizontal" : props.layout;
540
541
  return /* @__PURE__ */ jsx(AppLogo, { name: nama, tagline, glyph, color: color ?? warnaAplikasi(kode.toLowerCase()), ...props, layout, "data-memuat": logo.memuat || void 0 });
541
542
  }
543
+ var PROFIL_URL = "https://profile.unipo.ac.id";
544
+ var SSO_URL = "https://sso.unipo.ac.id";
545
+ function tautanAkun(profilUrl = PROFIL_URL, ssoUrl = SSO_URL, ganti = {}) {
546
+ const p = profilUrl.replace(/\/+$/, "");
547
+ const s = ssoUrl.replace(/\/+$/, "");
548
+ return {
549
+ profil: `${p}/`,
550
+ ubahProfil: `${p}/data-pribadi`,
551
+ foto: `${p}/?ubah=foto`,
552
+ password: `${p}/keamanan`,
553
+ keamanan: `${s}/akun`,
554
+ keluar: `${s}/logout`,
555
+ ...ganti
556
+ };
557
+ }
558
+ function subjudulAkun(a) {
559
+ return [a.username, a.peran ?? a.level].filter(Boolean).join(" \xB7 ");
560
+ }
561
+ var LABEL_ITEM = {
562
+ profil: { label: "Profil saya", ikon: /* @__PURE__ */ jsx(UserRound, {}), kunci: "profil" },
563
+ ubah: { label: "Ubah profil", ikon: /* @__PURE__ */ jsx(PenLine, {}), kunci: "ubahProfil" },
564
+ foto: { label: "Ganti foto", ikon: /* @__PURE__ */ jsx(IdCard, {}), kunci: "foto" },
565
+ password: { label: "Ganti password", ikon: /* @__PURE__ */ jsx(KeyRound, {}), kunci: "password" },
566
+ keamanan: { label: "Keamanan akun", ikon: /* @__PURE__ */ jsx(ShieldCheck, {}), kunci: "keamanan" }
567
+ };
568
+ var UKURAN_AVATAR = { pil: "sm", nama: "sm", avatar: "md", sidebar: "md", ikon: "xs" };
569
+ function Kelengkapan({ persen, href, tabBaru }) {
570
+ const p = Math.max(0, Math.min(100, Math.round(persen)));
571
+ return /* @__PURE__ */ jsxs(Menu$1.LinkItem, { href, className: "u-akun-lengkap", target: tabBaru ? "_blank" : void 0, rel: tabBaru ? "noopener" : void 0, children: [
572
+ /* @__PURE__ */ jsxs("span", { className: "u-akun-lengkap-teks", children: [
573
+ /* @__PURE__ */ jsx("span", { children: "Lengkapi profil" }),
574
+ /* @__PURE__ */ jsxs("b", { children: [
575
+ p,
576
+ "%"
577
+ ] })
578
+ ] }),
579
+ /* @__PURE__ */ jsx("span", { className: "u-akun-bilah", role: "progressbar", "aria-valuenow": p, "aria-valuemin": 0, "aria-valuemax": 100, "aria-label": "Kelengkapan profil", children: /* @__PURE__ */ jsx("span", { style: { width: `${p}%` } }) })
580
+ ] });
581
+ }
582
+ function MenuAkun({
583
+ pengguna,
584
+ varian = "pil",
585
+ item = ["profil", "ubah", "keamanan"],
586
+ profilUrl,
587
+ ssoUrl,
588
+ tautan,
589
+ kelengkapan,
590
+ peranLain,
591
+ onGantiPeran,
592
+ tema,
593
+ onTema,
594
+ menu = [],
595
+ onKeluar,
596
+ labelKeluar = "Keluar dari semua aplikasi",
597
+ tabBaru,
598
+ align,
599
+ side,
600
+ className
601
+ }) {
602
+ const t = tautanAkun(profilUrl, ssoUrl, tautan);
603
+ const sub = subjudulAkun(pengguna);
604
+ const belumLengkap = kelengkapan != null && kelengkapan < 100;
605
+ const target = tabBaru ? { target: "_blank", rel: "noopener" } : {};
606
+ const avatar = /* @__PURE__ */ jsx(Avatar, { name: pengguna.nama, src: pengguna.foto, size: UKURAN_AVATAR[varian], status: pengguna.status });
607
+ const pemicu = varian === "avatar" ? /* @__PURE__ */ jsx("button", { type: "button", className: cn("u-akun-pemicu", className), "data-varian": "avatar", "data-cincin": belumLengkap ? "" : void 0, "aria-label": `Menu akun ${pengguna.nama}`, children: avatar }) : varian === "ikon" ? /* @__PURE__ */ jsx("button", { type: "button", className: cn("u-akun-pemicu", className), "data-varian": "ikon", "aria-label": `Menu akun ${pengguna.nama}`, children: /* @__PURE__ */ jsx(UserRound, {}) }) : /* @__PURE__ */ jsxs("button", { type: "button", className: cn("u-akun-pemicu", className), "data-varian": varian, "aria-label": `Menu akun ${pengguna.nama}`, children: [
608
+ avatar,
609
+ /* @__PURE__ */ jsxs("span", { className: "u-akun-teks", children: [
610
+ /* @__PURE__ */ jsx("b", { children: pengguna.nama }),
611
+ varian !== "pil" && sub && /* @__PURE__ */ jsx("small", { children: sub })
612
+ ] }),
613
+ varian === "sidebar" ? /* @__PURE__ */ jsx(ChevronsUpDown, { className: "u-akun-panah", "aria-hidden": true }) : /* @__PURE__ */ jsx(ChevronDown, { className: "u-akun-panah", "aria-hidden": true })
614
+ ] });
615
+ const isiMenu = (it, i) => {
616
+ if (it.type === "separator") return /* @__PURE__ */ jsx(Menu$1.Separator, { className: "u-menu-separator" }, `x${i}`);
617
+ if (it.type === "label")
618
+ return /* @__PURE__ */ jsx("div", { className: "u-menu-label", children: it.label }, `x${i}`);
619
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
620
+ it.icon,
621
+ /* @__PURE__ */ jsx("span", { children: it.label }),
622
+ it.shortcut && /* @__PURE__ */ jsx("span", { className: "u-menu-shortcut", children: it.shortcut })
623
+ ] });
624
+ return it.href ? /* @__PURE__ */ jsx(Menu$1.LinkItem, { href: it.href, className: "u-menu-item", children: inner }, `x${i}`) : /* @__PURE__ */ jsx(Menu$1.Item, { className: "u-menu-item", onClick: it.onSelect, disabled: it.disabled, "data-variant": it.destructive ? "destructive" : void 0, children: inner }, `x${i}`);
625
+ };
626
+ return /* @__PURE__ */ jsxs(Menu$1.Root, { children: [
627
+ /* @__PURE__ */ jsx(Menu$1.Trigger, { render: pemicu }),
628
+ /* @__PURE__ */ jsx(Menu$1.Portal, { children: /* @__PURE__ */ jsx(Menu$1.Positioner, { className: "u-popup-positioner", align: align ?? (varian === "sidebar" ? "start" : "end"), side: side ?? (varian === "sidebar" ? "top" : "bottom"), sideOffset: 8, children: /* @__PURE__ */ jsxs(Menu$1.Popup, { className: "u-menu u-akun-menu", children: [
629
+ /* @__PURE__ */ jsxs("div", { className: "u-akun-kepala", children: [
630
+ /* @__PURE__ */ jsx(Avatar, { name: pengguna.nama, src: pengguna.foto, size: "lg" }),
631
+ /* @__PURE__ */ jsxs("div", { children: [
632
+ /* @__PURE__ */ jsx("b", { children: pengguna.nama }),
633
+ sub && /* @__PURE__ */ jsx("small", { children: sub }),
634
+ pengguna.unit && /* @__PURE__ */ jsx("small", { children: pengguna.unit })
635
+ ] })
636
+ ] }),
637
+ belumLengkap && /* @__PURE__ */ jsx(Kelengkapan, { persen: kelengkapan, href: t.ubahProfil, tabBaru }),
638
+ /* @__PURE__ */ jsx(Menu$1.Separator, { className: "u-menu-separator" }),
639
+ item.map((k) => /* @__PURE__ */ jsxs(Menu$1.LinkItem, { href: t[LABEL_ITEM[k].kunci], className: "u-menu-item", ...target, children: [
640
+ LABEL_ITEM[k].ikon,
641
+ /* @__PURE__ */ jsx("span", { children: LABEL_ITEM[k].label })
642
+ ] }, k)),
643
+ peranLain && peranLain.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
644
+ /* @__PURE__ */ jsx(Menu$1.Separator, { className: "u-menu-separator" }),
645
+ /* @__PURE__ */ jsx("div", { className: "u-menu-label", children: "Masuk sebagai" }),
646
+ peranLain.map((p) => /* @__PURE__ */ jsxs(Menu$1.Item, { className: "u-menu-item", onClick: () => onGantiPeran?.(p.kode), "data-aktif": p.aktif ? "" : void 0, children: [
647
+ /* @__PURE__ */ jsx(Users, {}),
648
+ /* @__PURE__ */ jsx("span", { children: p.label }),
649
+ p.aktif && /* @__PURE__ */ jsx(Check, { className: "u-akun-centang", "aria-label": "Aktif" })
650
+ ] }, p.kode))
651
+ ] }),
652
+ tema && onTema && /* @__PURE__ */ jsxs(Fragment, { children: [
653
+ /* @__PURE__ */ jsx(Menu$1.Separator, { className: "u-menu-separator" }),
654
+ /* @__PURE__ */ jsx("div", { className: "u-akun-tema", role: "group", "aria-label": "Tema", children: [
655
+ ["terang", /* @__PURE__ */ jsx(Sun, {}, "s"), "Terang"],
656
+ ["gelap", /* @__PURE__ */ jsx(Moon, {}, "m"), "Gelap"],
657
+ ["sistem", /* @__PURE__ */ jsx(Monitor, {}, "o"), "Sistem"]
658
+ ].map(([v, ikon, label]) => /* @__PURE__ */ jsxs("button", { type: "button", "aria-pressed": tema === v, onClick: () => onTema(v), children: [
659
+ ikon,
660
+ label
661
+ ] }, v)) })
662
+ ] }),
663
+ menu.length > 0 && /* @__PURE__ */ jsx(Menu$1.Separator, { className: "u-menu-separator" }),
664
+ menu.map(isiMenu),
665
+ /* @__PURE__ */ jsx(Menu$1.Separator, { className: "u-menu-separator" }),
666
+ onKeluar ? /* @__PURE__ */ jsxs(Menu$1.Item, { className: "u-menu-item", "data-variant": "destructive", onClick: onKeluar, children: [
667
+ /* @__PURE__ */ jsx(LogOut, {}),
668
+ /* @__PURE__ */ jsx("span", { children: labelKeluar })
669
+ ] }) : /* @__PURE__ */ jsxs(Menu$1.LinkItem, { href: t.keluar, className: "u-menu-item", "data-variant": "destructive", children: [
670
+ /* @__PURE__ */ jsx(LogOut, {}),
671
+ /* @__PURE__ */ jsx("span", { children: labelKeluar })
672
+ ] })
673
+ ] }) }) })
674
+ ] });
675
+ }
676
+ function KartuAkun({ pengguna, varian = "kartu", profilUrl, ssoUrl, tautan, kelengkapan, statistik, aksi, onKeluar, tabBaru, className }) {
677
+ const t = tautanAkun(profilUrl, ssoUrl, tautan);
678
+ const sub = subjudulAkun(pengguna);
679
+ const target = tabBaru ? { target: "_blank", rel: "noopener" } : {};
680
+ const p = kelengkapan == null ? null : Math.max(0, Math.min(100, Math.round(kelengkapan)));
681
+ const tombol = aksi === void 0 ? /* @__PURE__ */ jsxs("div", { className: "u-akun-aksi", children: [
682
+ /* @__PURE__ */ jsxs("a", { className: "u-button", "data-variant": "primary", "data-size": "sm", href: t.ubahProfil, ...target, children: [
683
+ /* @__PURE__ */ jsx(PenLine, {}),
684
+ "Ubah profil"
685
+ ] }),
686
+ /* @__PURE__ */ jsxs("a", { className: "u-button", "data-variant": "outline", "data-size": "sm", href: t.keamanan, children: [
687
+ /* @__PURE__ */ jsx(ShieldCheck, {}),
688
+ "Keamanan akun"
689
+ ] }),
690
+ onKeluar && /* @__PURE__ */ jsxs("button", { type: "button", className: "u-button", "data-variant": "ghost", "data-size": "sm", onClick: onKeluar, children: [
691
+ /* @__PURE__ */ jsx(LogOut, {}),
692
+ "Keluar"
693
+ ] })
694
+ ] }) : aksi === null ? null : /* @__PURE__ */ jsx("div", { className: "u-akun-aksi", children: aksi });
695
+ if (varian === "baris") {
696
+ return /* @__PURE__ */ jsxs("a", { className: cn("u-akun-kartu", className), "data-varian": "baris", href: t.profil, ...target, children: [
697
+ /* @__PURE__ */ jsx(Avatar, { name: pengguna.nama, src: pengguna.foto, size: "md", status: pengguna.status }),
698
+ /* @__PURE__ */ jsxs("span", { className: "u-akun-teks", children: [
699
+ /* @__PURE__ */ jsx("b", { children: pengguna.nama }),
700
+ sub && /* @__PURE__ */ jsx("small", { children: sub })
701
+ ] }),
702
+ p != null && p < 100 && /* @__PURE__ */ jsxs("span", { className: "u-akun-persen", children: [
703
+ p,
704
+ "%"
705
+ ] }),
706
+ /* @__PURE__ */ jsx(PenLine, { className: "u-akun-panah", "aria-hidden": true })
707
+ ] });
708
+ }
709
+ return /* @__PURE__ */ jsxs("section", { className: cn("u-akun-kartu", className), "data-varian": varian, children: [
710
+ varian === "sampul" && /* @__PURE__ */ jsx("div", { className: "u-akun-sampul", "aria-hidden": true }),
711
+ /* @__PURE__ */ jsxs("div", { className: "u-akun-identitas", children: [
712
+ /* @__PURE__ */ jsx("a", { href: t.foto, className: "u-akun-foto", "aria-label": "Ganti foto profil", ...target, children: /* @__PURE__ */ jsx(Avatar, { name: pengguna.nama, src: pengguna.foto, size: varian === "kartu" ? "lg" : "xl", status: pengguna.status }) }),
713
+ /* @__PURE__ */ jsxs("div", { className: "u-akun-teks", children: [
714
+ /* @__PURE__ */ jsx("b", { children: pengguna.nama }),
715
+ sub && /* @__PURE__ */ jsx("small", { children: sub }),
716
+ pengguna.unit && /* @__PURE__ */ jsx("small", { children: pengguna.unit }),
717
+ pengguna.email && /* @__PURE__ */ jsx("small", { children: pengguna.email })
718
+ ] })
719
+ ] }),
720
+ p != null && /* @__PURE__ */ jsxs("a", { className: "u-akun-lengkap", href: t.ubahProfil, ...target, "data-penuh": p >= 100 ? "" : void 0, children: [
721
+ /* @__PURE__ */ jsxs("span", { className: "u-akun-lengkap-teks", children: [
722
+ /* @__PURE__ */ jsx("span", { children: p >= 100 ? "Profil lengkap" : "Kelengkapan profil" }),
723
+ /* @__PURE__ */ jsxs("b", { children: [
724
+ p,
725
+ "%"
726
+ ] })
727
+ ] }),
728
+ /* @__PURE__ */ jsx("span", { className: "u-akun-bilah", role: "progressbar", "aria-valuenow": p, "aria-valuemin": 0, "aria-valuemax": 100, "aria-label": "Kelengkapan profil", children: /* @__PURE__ */ jsx("span", { style: { width: `${p}%` } }) })
729
+ ] }),
730
+ statistik && statistik.length > 0 && /* @__PURE__ */ jsx("dl", { className: "u-akun-statistik", children: statistik.map((s) => /* @__PURE__ */ jsxs("div", { children: [
731
+ /* @__PURE__ */ jsx("dt", { children: s.label }),
732
+ /* @__PURE__ */ jsx("dd", { children: s.nilai })
733
+ ] }, s.label)) }),
734
+ tombol
735
+ ] });
736
+ }
542
737
  var LABEL = { ok: "Normal", degraded: "Lambat", down: "Gangguan", maintenance: "Pemeliharaan", off: "Nonaktif", checking: "Memeriksa" };
543
738
  var ICON = {
544
739
  ok: /* @__PURE__ */ jsx(CheckCircle2, {}),
@@ -1105,6 +1300,6 @@ function Hero({ eyebrow, title, description, actions, stats, media, image, varia
1105
1300
  ] }) });
1106
1301
  }
1107
1302
 
1108
- export { APP_COLORS, APP_GLYPHS, AgendaList, AnnouncementList, AppLogo, DateTile, EVENT_COLORS, EventCalendar, EventCard, EventLegend, Faq, Hero, LatencyIndicator, LogoAplikasi, LogoGambar, Navbar, NewsCard, NewsCardSkeleton, NewsGrid, RankedList, Section, ServiceList, ServiceStatusBadge, ServiceStatusPanel, StatusBanner, UnipoAppLogo, UnipoMark, UptimeBar, eventColor, eventsByDay, formatEventRange, glyphInisial, overallStatus, urlLogoSso, useLogoTersedia, useServiceChecks, warnaAplikasi };
1109
- //# sourceMappingURL=chunk-UEOAVWAZ.js.map
1110
- //# sourceMappingURL=chunk-UEOAVWAZ.js.map
1303
+ export { APP_COLORS, APP_GLYPHS, AgendaList, AnnouncementList, AppLogo, DateTile, EVENT_COLORS, EventCalendar, EventCard, EventLegend, Faq, Hero, KartuAkun, LatencyIndicator, LogoAplikasi, LogoGambar, MenuAkun, Navbar, NewsCard, NewsCardSkeleton, NewsGrid, PROFIL_URL, RankedList, SSO_URL, Section, ServiceList, ServiceStatusBadge, ServiceStatusPanel, StatusBanner, UnipoAppLogo, UnipoMark, UptimeBar, eventColor, eventsByDay, formatEventRange, glyphInisial, overallStatus, subjudulAkun, tautanAkun, urlLogoSso, useLogoTersedia, useServiceChecks, warnaAplikasi };
1304
+ //# sourceMappingURL=chunk-2CDMQI7K.js.map
1305
+ //# sourceMappingURL=chunk-2CDMQI7K.js.map