Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
Commit544d842unknown_key

polish(repo-home): 2026 hero + meta sidebar + empty-state CTA (parallel session 2.A)

Claude committed on May 17, 2026Parent: 58b822d
1 file changed+72648544d842e1ff022937f7108199a6a7f1abcfa8ccd
1 changed file+726−48
Modifiedsrc/routes/web.tsx+726−48View fileUnifiedSplit
531531 starred: false,
532532 archived: false,
533533 isTemplate: false,
534 forkCount: 0,
535 description: null as string | null,
536 pushedAt: null as Date | null,
537 createdAt: null as Date | null,
534538 };
535539 const [repoRow] = await db
536540 .select()
548552 starred: false,
549553 archived: false,
550554 isTemplate: false,
555 forkCount: 0,
556 description: null as string | null,
557 pushedAt: null as Date | null,
558 createdAt: null as Date | null,
551559 };
552560 let starred = false;
553561 if (user) {
568576 starred,
569577 archived: repoRow.isArchived,
570578 isTemplate: repoRow.isTemplate,
579 forkCount: repoRow.forkCount,
580 description: repoRow.description as string | null,
581 pushedAt: (repoRow.pushedAt as Date | null) ?? null,
582 createdAt: (repoRow.createdAt as Date | null) ?? null,
571583 };
572584 } catch {
573585 return {
575587 starred: false,
576588 archived: false,
577589 isTemplate: false,
590 forkCount: 0,
591 description: null as string | null,
592 pushedAt: null as Date | null,
593 createdAt: null as Date | null,
578594 };
579595 }
580596 })(),
581597 ]);
582 const { starCount, starred, archived, isTemplate } = starInfo;
598 const {
599 starCount,
600 starred,
601 archived,
602 isTemplate,
603 forkCount,
604 description,
605 pushedAt,
606 createdAt,
607 } = starInfo;
608
609 // Repo-home polish — shared style block (Block 2.A — parallel session 2.A).
610 // Scoped via .repo-home-* class prefix to prevent bleed into other surfaces.
611 const repoHomeCss = `
612 .repo-home-hero {
613 position: relative;
614 margin-bottom: var(--space-5);
615 padding: var(--space-5) var(--space-6);
616 background: var(--bg-elevated);
617 border: 1px solid var(--border);
618 border-radius: 16px;
619 overflow: hidden;
620 }
621 .repo-home-hero::before {
622 content: '';
623 position: absolute;
624 top: 0; left: 0; right: 0;
625 height: 2px;
626 background: linear-gradient(90deg, transparent 0%, #8c6dff 30%, #36c5d6 70%, transparent 100%);
627 opacity: 0.7;
628 pointer-events: none;
629 }
630 .repo-home-hero-orb-wrap {
631 position: absolute;
632 inset: -25% -10% auto auto;
633 width: 360px;
634 height: 360px;
635 pointer-events: none;
636 z-index: 0;
637 }
638 .repo-home-hero-orb {
639 position: absolute;
640 inset: 0;
641 background: radial-gradient(circle, rgba(140,109,255,0.18), rgba(54,197,214,0.09) 45%, transparent 70%);
642 filter: blur(80px);
643 opacity: 0.7;
644 animation: repoHomeOrb 14s ease-in-out infinite;
645 }
646 @keyframes repoHomeOrb {
647 0%, 100% { transform: scale(1) translate(0, 0); opacity: 0.55; }
648 50% { transform: scale(1.1) translate(-10px, 8px); opacity: 0.8; }
649 }
650 @media (prefers-reduced-motion: reduce) {
651 .repo-home-hero-orb { animation: none; }
652 }
653 .repo-home-hero-inner {
654 position: relative;
655 z-index: 1;
656 }
657 .repo-home-hero .repo-header { margin-bottom: var(--space-3); }
658 .repo-home-eyebrow {
659 font-size: 12px;
660 font-family: var(--font-mono);
661 color: var(--text-muted);
662 letter-spacing: 0.1em;
663 text-transform: uppercase;
664 margin-bottom: var(--space-2);
665 }
666 .repo-home-eyebrow strong { color: var(--accent); font-weight: 600; }
667 .repo-home-description {
668 font-size: 15px;
669 line-height: 1.55;
670 color: var(--text);
671 margin: 0;
672 max-width: 720px;
673 }
674 .repo-home-description-empty {
675 font-size: 14px;
676 color: var(--text-muted);
677 font-style: italic;
678 margin: 0;
679 }
680 .repo-home-stat-row {
681 display: flex;
682 flex-wrap: wrap;
683 gap: var(--space-4);
684 margin-top: var(--space-3);
685 font-size: 13px;
686 color: var(--text-muted);
687 }
688 .repo-home-stat {
689 display: inline-flex;
690 align-items: center;
691 gap: 6px;
692 }
693 .repo-home-stat strong {
694 color: var(--text-strong);
695 font-weight: 600;
696 font-variant-numeric: tabular-nums;
697 }
698 .repo-home-stat .repo-home-stat-icon {
699 color: var(--text-faint);
700 font-size: 14px;
701 line-height: 1;
702 }
703 .repo-home-stat a {
704 color: var(--text-muted);
705 transition: color var(--t-fast) var(--ease);
706 }
707 .repo-home-stat a:hover { color: var(--accent); text-decoration: none; }
708
709 /* Two-column layout: file tree + sidebar */
710 .repo-home-grid {
711 display: grid;
712 grid-template-columns: minmax(0, 1fr) 280px;
713 gap: var(--space-5);
714 align-items: start;
715 }
716 @media (max-width: 960px) {
717 .repo-home-grid { grid-template-columns: minmax(0, 1fr); }
718 }
719 .repo-home-main { min-width: 0; }
720
721 /* Sidebar card */
722 .repo-home-side {
723 display: flex;
724 flex-direction: column;
725 gap: var(--space-4);
726 }
727 .repo-home-side-card {
728 background: var(--bg-elevated);
729 border: 1px solid var(--border);
730 border-radius: 12px;
731 padding: var(--space-4);
732 }
733 .repo-home-side-title {
734 font-size: 11px;
735 font-family: var(--font-mono);
736 letter-spacing: 0.12em;
737 text-transform: uppercase;
738 color: var(--text-muted);
739 margin: 0 0 var(--space-3);
740 font-weight: 600;
741 }
742 .repo-home-side-row {
743 display: flex;
744 justify-content: space-between;
745 align-items: center;
746 gap: var(--space-2);
747 font-size: 13px;
748 padding: 6px 0;
749 border-top: 1px solid var(--border);
750 }
751 .repo-home-side-row:first-of-type { border-top: 0; padding-top: 0; }
752 .repo-home-side-key {
753 color: var(--text-muted);
754 display: inline-flex;
755 align-items: center;
756 gap: 6px;
757 }
758 .repo-home-side-val {
759 color: var(--text-strong);
760 font-weight: 500;
761 font-variant-numeric: tabular-nums;
762 max-width: 60%;
763 text-align: right;
764 overflow: hidden;
765 text-overflow: ellipsis;
766 white-space: nowrap;
767 }
768 .repo-home-side-val a { color: var(--text-strong); }
769 .repo-home-side-val a:hover { color: var(--accent); text-decoration: none; }
770
771 /* Clone / Code tabs */
772 .repo-home-clone {
773 background: var(--bg-elevated);
774 border: 1px solid var(--border);
775 border-radius: 12px;
776 overflow: hidden;
777 }
778 .repo-home-clone-tabs {
779 display: flex;
780 gap: 0;
781 background: var(--bg-secondary);
782 border-bottom: 1px solid var(--border);
783 padding: 0 var(--space-2);
784 }
785 .repo-home-clone-tab {
786 appearance: none;
787 background: transparent;
788 border: 0;
789 border-bottom: 2px solid transparent;
790 padding: 9px 12px;
791 font-size: 12px;
792 font-weight: 500;
793 color: var(--text-muted);
794 cursor: pointer;
795 transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
796 font-family: inherit;
797 margin-bottom: -1px;
798 }
799 .repo-home-clone-tab:hover { color: var(--text-strong); }
800 .repo-home-clone-tab[aria-selected="true"] {
801 color: var(--text-strong);
802 border-bottom-color: var(--accent);
803 }
804 .repo-home-clone-body {
805 padding: var(--space-3);
806 display: flex;
807 align-items: center;
808 gap: var(--space-2);
809 }
810 .repo-home-clone-input {
811 flex: 1;
812 min-width: 0;
813 font-family: var(--font-mono);
814 font-size: 12px;
815 background: var(--bg);
816 border: 1px solid var(--border);
817 border-radius: 8px;
818 padding: 8px 10px;
819 color: var(--text-strong);
820 overflow: hidden;
821 text-overflow: ellipsis;
822 white-space: nowrap;
823 }
824 .repo-home-clone-copy {
825 appearance: none;
826 background: var(--bg-secondary);
827 border: 1px solid var(--border);
828 color: var(--text-strong);
829 border-radius: 8px;
830 padding: 8px 12px;
831 font-size: 12px;
832 font-weight: 600;
833 cursor: pointer;
834 transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
835 font-family: inherit;
836 }
837 .repo-home-clone-copy:hover { background: var(--bg-hover); border-color: var(--border-strong, var(--border)); }
838 .repo-home-clone-pane { display: none; }
839 .repo-home-clone-pane[data-active="true"] { display: flex; }
840
841 /* README card */
842 .repo-home-readme {
843 margin-top: var(--space-5);
844 background: var(--bg-elevated);
845 border: 1px solid var(--border);
846 border-radius: 12px;
847 overflow: hidden;
848 }
849 .repo-home-readme-head {
850 display: flex;
851 align-items: center;
852 gap: 8px;
853 padding: 10px 16px;
854 background: var(--bg-secondary);
855 border-bottom: 1px solid var(--border);
856 font-size: 13px;
857 color: var(--text-muted);
858 }
859 .repo-home-readme-head .repo-home-readme-icon {
860 color: var(--accent);
861 font-size: 14px;
862 }
863 .repo-home-readme-body {
864 padding: var(--space-5) var(--space-6);
865 }
866
867 /* Empty-state CTA */
868 .repo-home-empty {
869 position: relative;
870 margin-top: var(--space-4);
871 background: var(--bg-elevated);
872 border: 1px solid var(--border);
873 border-radius: 16px;
874 padding: var(--space-6);
875 overflow: hidden;
876 }
877 .repo-home-empty::before {
878 content: '';
879 position: absolute;
880 top: 0; left: 0; right: 0;
881 height: 2px;
882 background: linear-gradient(90deg, transparent 0%, #8c6dff 30%, #36c5d6 70%, transparent 100%);
883 opacity: 0.7;
884 pointer-events: none;
885 }
886 .repo-home-empty-eyebrow {
887 font-size: 12px;
888 font-family: var(--font-mono);
889 color: var(--accent);
890 letter-spacing: 0.12em;
891 text-transform: uppercase;
892 margin-bottom: var(--space-2);
893 font-weight: 600;
894 }
895 .repo-home-empty-title {
896 font-family: var(--font-display);
897 font-weight: 800;
898 letter-spacing: -0.025em;
899 font-size: clamp(22px, 3vw, 30px);
900 line-height: 1.1;
901 margin: 0 0 var(--space-2);
902 color: var(--text-strong);
903 }
904 .repo-home-empty-sub {
905 color: var(--text-muted);
906 font-size: 14px;
907 line-height: 1.55;
908 max-width: 640px;
909 margin: 0 0 var(--space-4);
910 }
911 .repo-home-empty-snippet {
912 background: var(--bg);
913 border: 1px solid var(--border);
914 border-radius: 10px;
915 padding: var(--space-3) var(--space-4);
916 font-family: var(--font-mono);
917 font-size: 12.5px;
918 line-height: 1.7;
919 color: var(--text-strong);
920 overflow-x: auto;
921 white-space: pre;
922 margin: 0;
923 }
924 .repo-home-empty-snippet .repo-home-cmt { color: var(--text-faint); }
925 .repo-home-empty-snippet .repo-home-cmd { color: var(--accent); }
926
927 @media (max-width: 720px) {
928 .repo-home-hero { padding: var(--space-4) var(--space-4); }
929 .repo-home-clone-body { flex-direction: column; align-items: stretch; }
930 .repo-home-clone-copy { width: 100%; }
931 }
932 `;
933 const cloneHttpsUrl = `${config.appBaseUrl}/${owner}/${repo}.git`;
934 // Best-effort SSH URL. If APP_BASE_URL is a hostname, this looks right; for
935 // localhost it'll still render and just be slightly silly (which is fine for dev).
936 let cloneSshUrl = `git@gluecron.com:${owner}/${repo}.git`;
937 try {
938 const host = new URL(config.appBaseUrl).hostname;
939 if (host && host !== "localhost" && host !== "127.0.0.1") {
940 cloneSshUrl = `git@${host}:${owner}/${repo}.git`;
941 }
942 } catch {
943 // Fall through to default.
944 }
945 const cloneCliCmd = `gluecron clone ${owner}/${repo}`;
946 const formatRelative = (date: Date | null): string => {
947 if (!date) return "never";
948 const ms = Date.now() - date.getTime();
949 const s = Math.max(0, Math.round(ms / 1000));
950 if (s < 60) return "just now";
951 const m = Math.round(s / 60);
952 if (m < 60) return `${m} min ago`;
953 const h = Math.round(m / 60);
954 if (h < 24) return `${h}h ago`;
955 const d = Math.round(h / 24);
956 if (d < 30) return `${d}d ago`;
957 const mo = Math.round(d / 30);
958 if (mo < 12) return `${mo}mo ago`;
959 const y = Math.round(d / 365);
960 return `${y}y ago`;
961 };
583962
584963 if (tree.length === 0) {
585964 return c.html(
586965 <Layout title={`${owner}/${repo}`} user={user}>
587 <RepoHeader
588 owner={owner}
589 repo={repo}
590 starCount={starCount}
591 starred={starred}
592 currentUser={user?.username}
593 archived={archived}
594 isTemplate={isTemplate}
595 />
966 <style dangerouslySetInnerHTML={{ __html: repoHomeCss }} />
967 <div class="repo-home-hero">
968 <div class="repo-home-hero-orb-wrap" aria-hidden="true">
969 <div class="repo-home-hero-orb" />
970 </div>
971 <div class="repo-home-hero-inner">
972 <div class="repo-home-eyebrow">
973 <strong>Repository</strong> · {owner}
974 </div>
975 <RepoHeader
976 owner={owner}
977 repo={repo}
978 starCount={starCount}
979 starred={starred}
980 forkCount={forkCount}
981 currentUser={user?.username}
982 archived={archived}
983 isTemplate={isTemplate}
984 />
985 {description ? (
986 <p class="repo-home-description">{description}</p>
987 ) : (
988 <p class="repo-home-description-empty">
989 No description yet — push a README to tell the world what this
990 ships.
991 </p>
992 )}
993 </div>
994 </div>
596995 <RepoNav owner={owner} repo={repo} active="code" />
597 <div class="empty-state">
598 <h2>Empty repository</h2>
599 <p>Get started by pushing code:</p>
600 <pre>{`git remote add gluecron ${config.appBaseUrl}/${owner}/${repo}.git
601git push -u gluecron main`}</pre>
996 <div class="repo-home-empty">
997 <div class="repo-home-empty-eyebrow">Getting started</div>
998 <h2 class="repo-home-empty-title">
999 Push your first commit to{" "}
1000 <span class="gradient-text">{repo}</span>.
1001 </h2>
1002 <p class="repo-home-empty-sub">
1003 This repository is empty. Paste the snippet below in an existing
1004 project directory to wire it up to Gluecron — your push triggers
1005 gate checks and AI review automatically.
1006 </p>
1007 <pre class="repo-home-empty-snippet">
1008 <span class="repo-home-cmt">
1009 # from an existing project directory
1010 </span>
1011 {"\n"}
1012 <span class="repo-home-cmd">git remote add</span>
1013 {` origin ${cloneHttpsUrl}`}
1014 {"\n"}
1015 <span class="repo-home-cmd">git branch</span>
1016 {` -M main`}
1017 {"\n"}
1018 <span class="repo-home-cmd">git push</span>
1019 {` -u origin main`}
1020 </pre>
6021021 </div>
6031022 </Layout>
6041023 );
6061025
6071026 const readme = await getReadme(owner, repo, defaultBranch);
6081027
1028 // Sidebar facts — derived from data we already have.
1029 const fileCount = tree.filter((e: any) => e.type !== "tree").length;
1030 const dirCount = tree.filter((e: any) => e.type === "tree").length;
1031
6091032 return c.html(
6101033 <Layout title={`${owner}/${repo}`} user={user}>
611 <RepoHeader
612 owner={owner}
613 repo={repo}
614 starCount={starCount}
615 starred={starred}
616 currentUser={user?.username}
617 archived={archived}
618 isTemplate={isTemplate}
619 />
1034 <style dangerouslySetInnerHTML={{ __html: repoHomeCss }} />
1035 <div class="repo-home-hero">
1036 <div class="repo-home-hero-orb-wrap" aria-hidden="true">
1037 <div class="repo-home-hero-orb" />
1038 </div>
1039 <div class="repo-home-hero-inner">
1040 <div class="repo-home-eyebrow">
1041 <strong>Repository</strong> · {owner}
1042 </div>
1043 <RepoHeader
1044 owner={owner}
1045 repo={repo}
1046 starCount={starCount}
1047 starred={starred}
1048 forkCount={forkCount}
1049 currentUser={user?.username}
1050 archived={archived}
1051 isTemplate={isTemplate}
1052 />
1053 {description ? (
1054 <p class="repo-home-description">{description}</p>
1055 ) : (
1056 <p class="repo-home-description-empty">
1057 No description yet.
1058 </p>
1059 )}
1060 <div class="repo-home-stat-row" aria-label="Repository stats">
1061 <span class="repo-home-stat" title="Default branch">
1062 <span class="repo-home-stat-icon">{"⎇"}</span>
1063 <strong>{defaultBranch}</strong>
1064 </span>
1065 <a
1066 href={`/${owner}/${repo}/commits/${defaultBranch}`}
1067 class="repo-home-stat"
1068 title="Browse all branches"
1069 >
1070 <span class="repo-home-stat-icon">{"⊢"}</span>
1071 <strong>{branches.length}</strong>{" "}
1072 branch{branches.length === 1 ? "" : "es"}
1073 </a>
1074 <span class="repo-home-stat" title="Top-level entries">
1075 <span class="repo-home-stat-icon">{"■"}</span>
1076 <strong>{fileCount}</strong> file{fileCount === 1 ? "" : "s"}
1077 {dirCount > 0 && (
1078 <>
1079 {" · "}
1080 <strong>{dirCount}</strong> dir{dirCount === 1 ? "" : "s"}
1081 </>
1082 )}
1083 </span>
1084 {pushedAt && (
1085 <span class="repo-home-stat" title={`Last push: ${pushedAt.toISOString()}`}>
1086 <span class="repo-home-stat-icon">{"↻"}</span>
1087 Updated <strong>{formatRelative(pushedAt)}</strong>
1088 </span>
1089 )}
1090 </div>
1091 </div>
1092 </div>
6201093 {isTemplate && user && user.username !== owner && (
6211094 <div
6221095 class="panel"
6461119 </div>
6471120 )}
6481121 <RepoNav owner={owner} repo={repo} active="code" />
649 <BranchSwitcher
650 owner={owner}
651 repo={repo}
652 currentRef={defaultBranch}
653 branches={branches}
654 pathType="tree"
655 />
656 <FileTable
657 entries={tree}
658 owner={owner}
659 repo={repo}
660 ref={defaultBranch}
661 path=""
662 />
663 {readme && (() => {
664 const readmeHtml = renderMarkdown(readme);
665 return (
666 <div class="blob-view" style="margin-top: 20px">
667 <div class="blob-header">README.md</div>
668 <style>{markdownCss}</style>
669 <div class="markdown-body">
670 {html([readmeHtml] as unknown as TemplateStringsArray)}
1122 <div class="repo-home-grid">
1123 <div class="repo-home-main">
1124 <BranchSwitcher
1125 owner={owner}
1126 repo={repo}
1127 currentRef={defaultBranch}
1128 branches={branches}
1129 pathType="tree"
1130 />
1131 <FileTable
1132 entries={tree}
1133 owner={owner}
1134 repo={repo}
1135 ref={defaultBranch}
1136 path=""
1137 />
1138 {readme && (() => {
1139 const readmeHtml = renderMarkdown(readme);
1140 return (
1141 <div class="repo-home-readme">
1142 <div class="repo-home-readme-head">
1143 <span class="repo-home-readme-icon">{"☰"}</span>
1144 <span>README.md</span>
1145 </div>
1146 <style>{markdownCss}</style>
1147 <div class="markdown-body repo-home-readme-body">
1148 {html([readmeHtml] as unknown as TemplateStringsArray)}
1149 </div>
1150 </div>
1151 );
1152 })()}
1153 </div>
1154 <aside class="repo-home-side" aria-label="Repository details">
1155 <div class="repo-home-clone">
1156 <div class="repo-home-clone-tabs" role="tablist" aria-label="Clone protocol">
1157 <button
1158 type="button"
1159 class="repo-home-clone-tab"
1160 role="tab"
1161 aria-selected="true"
1162 data-pane="https"
1163 data-repo-home-clone-tab
1164 >
1165 HTTPS
1166 </button>
1167 <button
1168 type="button"
1169 class="repo-home-clone-tab"
1170 role="tab"
1171 aria-selected="false"
1172 data-pane="ssh"
1173 data-repo-home-clone-tab
1174 >
1175 SSH
1176 </button>
1177 <button
1178 type="button"
1179 class="repo-home-clone-tab"
1180 role="tab"
1181 aria-selected="false"
1182 data-pane="cli"
1183 data-repo-home-clone-tab
1184 >
1185 CLI
1186 </button>
6711187 </div>
1188 <div
1189 class="repo-home-clone-pane"
1190 data-pane="https"
1191 data-active="true"
1192 role="tabpanel"
1193 >
1194 <div class="repo-home-clone-body">
1195 <input
1196 class="repo-home-clone-input"
1197 type="text"
1198 value={cloneHttpsUrl}
1199 readonly
1200 aria-label="HTTPS clone URL"
1201 data-repo-home-clone-input
1202 />
1203 <button
1204 type="button"
1205 class="repo-home-clone-copy"
1206 data-repo-home-copy={cloneHttpsUrl}
1207 >
1208 Copy
1209 </button>
1210 </div>
1211 </div>
1212 <div
1213 class="repo-home-clone-pane"
1214 data-pane="ssh"
1215 data-active="false"
1216 role="tabpanel"
1217 >
1218 <div class="repo-home-clone-body">
1219 <input
1220 class="repo-home-clone-input"
1221 type="text"
1222 value={cloneSshUrl}
1223 readonly
1224 aria-label="SSH clone URL"
1225 data-repo-home-clone-input
1226 />
1227 <button
1228 type="button"
1229 class="repo-home-clone-copy"
1230 data-repo-home-copy={cloneSshUrl}
1231 >
1232 Copy
1233 </button>
1234 </div>
1235 </div>
1236 <div
1237 class="repo-home-clone-pane"
1238 data-pane="cli"
1239 data-active="false"
1240 role="tabpanel"
1241 >
1242 <div class="repo-home-clone-body">
1243 <input
1244 class="repo-home-clone-input"
1245 type="text"
1246 value={cloneCliCmd}
1247 readonly
1248 aria-label="Gluecron CLI clone command"
1249 data-repo-home-clone-input
1250 />
1251 <button
1252 type="button"
1253 class="repo-home-clone-copy"
1254 data-repo-home-copy={cloneCliCmd}
1255 >
1256 Copy
1257 </button>
1258 </div>
1259 </div>
1260 </div>
1261 <div class="repo-home-side-card">
1262 <h3 class="repo-home-side-title">About</h3>
1263 <div class="repo-home-side-row">
1264 <span class="repo-home-side-key">Default branch</span>
1265 <span class="repo-home-side-val">{defaultBranch}</span>
1266 </div>
1267 <div class="repo-home-side-row">
1268 <span class="repo-home-side-key">Branches</span>
1269 <span class="repo-home-side-val">
1270 <a href={`/${owner}/${repo}/commits/${defaultBranch}`}>
1271 {branches.length}
1272 </a>
1273 </span>
1274 </div>
1275 <div class="repo-home-side-row">
1276 <span class="repo-home-side-key">Stars</span>
1277 <span class="repo-home-side-val">{starCount}</span>
1278 </div>
1279 <div class="repo-home-side-row">
1280 <span class="repo-home-side-key">Forks</span>
1281 <span class="repo-home-side-val">{forkCount}</span>
1282 </div>
1283 {pushedAt && (
1284 <div class="repo-home-side-row">
1285 <span class="repo-home-side-key">Last push</span>
1286 <span class="repo-home-side-val">
1287 {formatRelative(pushedAt)}
1288 </span>
1289 </div>
1290 )}
1291 {createdAt && (
1292 <div class="repo-home-side-row">
1293 <span class="repo-home-side-key">Created</span>
1294 <span class="repo-home-side-val">
1295 {formatRelative(createdAt)}
1296 </span>
1297 </div>
1298 )}
1299 {(archived || isTemplate) && (
1300 <div class="repo-home-side-row">
1301 <span class="repo-home-side-key">State</span>
1302 <span class="repo-home-side-val">
1303 {archived ? "Archived" : "Template"}
1304 </span>
1305 </div>
1306 )}
6721307 </div>
673 );
674 })()}
1308 </aside>
1309 </div>
1310 <script
1311 dangerouslySetInnerHTML={{
1312 __html: `
1313 (function(){
1314 var tabs = document.querySelectorAll('[data-repo-home-clone-tab]');
1315 tabs.forEach(function(tab){
1316 tab.addEventListener('click', function(){
1317 var target = tab.getAttribute('data-pane');
1318 tabs.forEach(function(t){
1319 t.setAttribute('aria-selected', t === tab ? 'true' : 'false');
1320 });
1321 var panes = document.querySelectorAll('.repo-home-clone-pane');
1322 panes.forEach(function(p){
1323 p.setAttribute('data-active', p.getAttribute('data-pane') === target ? 'true' : 'false');
1324 });
1325 });
1326 });
1327 var copyBtns = document.querySelectorAll('[data-repo-home-copy]');
1328 copyBtns.forEach(function(btn){
1329 btn.addEventListener('click', function(){
1330 var text = btn.getAttribute('data-repo-home-copy') || '';
1331 var done = function(){
1332 var prev = btn.textContent;
1333 btn.textContent = 'Copied';
1334 setTimeout(function(){ btn.textContent = prev; }, 1200);
1335 };
1336 if (navigator.clipboard && navigator.clipboard.writeText) {
1337 navigator.clipboard.writeText(text).then(done, done);
1338 } else {
1339 var ta = document.createElement('textarea');
1340 ta.value = text;
1341 document.body.appendChild(ta);
1342 ta.select();
1343 try { document.execCommand('copy'); } catch (e) {}
1344 document.body.removeChild(ta);
1345 done();
1346 }
1347 });
1348 });
1349 })();
1350 `,
1351 }}
1352 />
6751353 </Layout>
6761354 );
6771355});
6781356