Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion web/apps/admin/src/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export const DEFAULT_DATE_FORMAT = "MMM DD, YYYY";
export const DEFAULT_TOKEN_PRODUCT_NAME = "token";

export const PERMISSIONS = {
Expand Down
8 changes: 0 additions & 8 deletions web/apps/admin/src/utils/helper.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import dayjs from 'dayjs';
import type { TableColumnMetadata } from '~/types/types';
import { DEFAULT_DATE_FORMAT } from './constants';
import { BillingAccount_Address } from '@raystack/proton/frontier';

const currencySymbolMap: Record<string, string> = {
Expand Down Expand Up @@ -48,12 +46,6 @@ export const capitalizeFirstLetter = (str: string) => {
export const keyToColumnMetaObject = (key: any) =>
({ key: key, name: key, value: key } as TableColumnMetadata);

/*
* @desc returns date string - Eg, June 13, 2025. return '-' if the date in the argument is invalid.
*/
export const getFormattedDateString = (date: string) =>
date ? dayjs(date).format(DEFAULT_DATE_FORMAT) : '-';

export const convertBillingAddressToString = (
address?: BillingAccount_Address
) => {
Expand Down
10 changes: 10 additions & 0 deletions web/sdk/admin/utils/connect-timestamp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,14 @@ export function isNullTimestamp(timestamp?: Timestamp): boolean {
return Number(timestamp.seconds) <= 0;
}

/** Canonical admin date format (matches Apsara). */
export const DATE_FORMAT = "DD MMM YYYY";

/** Formats a Timestamp, returning "-" for missing/null-time values (which would otherwise render as 01 Jan 1970). */
export function formatTimestamp(timestamp?: Timestamp, format: string = DATE_FORMAT): string {
if (isNullTimestamp(timestamp)) return "-";
const date = timestampToDayjs(timestamp);
return date ? date.format(format) : "-";
}

export type TimeStamp = Timestamp;
4 changes: 2 additions & 2 deletions web/sdk/admin/views/admins/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import { TerminologyEntity } from "../../hooks/useTerminology";
import styles from "./admins.module.css";

export const getColumns: (options?: {

Check warning on line 6 in web/sdk/admin/views/admins/columns.tsx

View workflow job for this annotation

GitHub Actions / JS SDK Lint

'options' is defined but never used
onNavigateToOrg?: (orgId: string) => void;

Check warning on line 7 in web/sdk/admin/views/admins/columns.tsx

View workflow job for this annotation

GitHub Actions / JS SDK Lint

'orgId' is defined but never used
t?: {
organization: TerminologyEntity;
};
Expand All @@ -20,13 +20,13 @@
cell: styles["first-column"],
header: styles["first-column"],
},
filterVariant: "text",
filterType: "string",
cell: (info) => info.getValue() || "-",
},
{
header: "Email",
accessorKey: "email",
filterVariant: "text",
filterType: "string",
cell: (info) => info.getValue() || "-",
},
{
Expand Down
10 changes: 4 additions & 6 deletions web/sdk/admin/views/audit-logs/columns.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { Badge, DataTableColumnDef, Flex, Text } from "@raystack/apsara";
import dayjs from "dayjs";
import styles from "./audit-logs.module.css";
import {
AuditRecord,
AuditRecordActor,
AuditRecordResource,
} from "@raystack/proton/frontier";
import {
formatTimestamp,
isNullTimestamp,
TimeStamp,
timestampToDate,
} from "../../utils/connect-timestamp";
} from "~/admin/utils/connect-timestamp";
import { ACTOR_TYPES, getActionBadgeColor } from "./util";
import { ComponentPropsWithoutRef } from "react";
import ActorCell from "./actor-cell";
Expand All @@ -25,7 +24,7 @@
}

export const getColumns = ({
groupCountMap,

Check warning on line 27 in web/sdk/admin/views/audit-logs/columns.tsx

View workflow job for this annotation

GitHub Actions / JS SDK Lint

'groupCountMap' is defined but never used
t,
}: getColumnsOptions): DataTableColumnDef<AuditRecord, unknown>[] => {
return [
Expand Down Expand Up @@ -113,14 +112,13 @@
if (isNullTimestamp(value)) {
return <Text>-</Text>;
}
const date = dayjs(timestampToDate(value));
return (
<Flex gap={1} direction="column">
<Text size="small" weight="medium">
{date.format("DD MMM YYYY")}
{formatTimestamp(value)}
</Text>
<Text size="small" variant="secondary">
{date.format("hh:mm A")}
{formatTimestamp(value, "hh:mm A")}
</Text>
</Flex>
);
Expand Down
9 changes: 3 additions & 6 deletions web/sdk/admin/views/audit-logs/sidepanel-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
import styles from "./audit-logs.module.css";
import { AuditRecord } from "@raystack/proton/frontier";
import { ACTOR_TYPES } from "./util";
import { timestampToDate } from "../../utils/connect-timestamp";
import dayjs from "dayjs";
import { formatTimestamp } from "~/admin/utils/connect-timestamp";
import { MapIcon } from "../../assets/icons/MapIcon";
import SidePanelLogDialog from "./sidepanel-log-dialog";
import ActorCell from "./actor-cell";
Expand All @@ -22,7 +21,7 @@

type SidePanelDetailsProps = Partial<AuditRecord> & {
onClose: () => void;
onNavigate?: (path: string) => void;

Check warning on line 24 in web/sdk/admin/views/audit-logs/sidepanel-details.tsx

View workflow job for this annotation

GitHub Actions / JS SDK Lint

'path' is defined but never used
};

type AuditSessionContext = {
Expand All @@ -44,8 +43,6 @@
const paths = useAdminPaths();
const { actor, event, resource, occurredAt, id, orgId, orgName, target } =
rest;
const date = dayjs(timestampToDate(occurredAt));

const session = actor?.metadata?.context as AuditSessionContext;
const location =
(session && `${session.Location.City}, ${session.Location.Country}`) || "-";
Expand Down Expand Up @@ -100,11 +97,11 @@
</List.Item>
<List.Item>
<List.Label minWidth="120px">Date</List.Label>
<List.Value>{date.format("DD MMM YYYY")}</List.Value>
<List.Value>{formatTimestamp(occurredAt)}</List.Value>
</List.Item>
<List.Item>
<List.Label minWidth="120px">Time</List.Label>
<List.Value>{date.format("hh:mm A")}</List.Value>
<List.Value>{formatTimestamp(occurredAt, "hh:mm A")}</List.Value>
</List.Item>
<List.Item>
<List.Label minWidth="120px">ID</List.Label>
Expand Down
17 changes: 4 additions & 13 deletions web/sdk/admin/views/invoices/columns.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { Amount, type DataTableColumnDef, Link, Text } from "@raystack/apsara";
import dayjs from "dayjs";
import type { SearchInvoicesResponse_Invoice } from "@raystack/proton/frontier";
import {
isNullTimestamp,
TimeStamp,
timestampToDate,
} from "../../utils/connect-timestamp";
import { formatTimestamp, TimeStamp } from "~/admin/utils/connect-timestamp";
import { TerminologyEntity } from "../../hooks/useTerminology";
import styles from "./invoices.module.css";

Expand All @@ -29,13 +24,9 @@ export const getColumns = ({ t }: GetColumnsOptions): DataTableColumnDef<
},
filterType: "date",
enableColumnFilter: true,
cell: ({ getValue }) => {
const value = getValue() as TimeStamp;
const date = isNullTimestamp(value)
? "-"
: dayjs(timestampToDate(value)).format("YYYY-MM-DD");
return <Text>{date}</Text>;
},
cell: ({ getValue }) => (
<Text>{formatTimestamp(getValue() as TimeStamp)}</Text>
),
enableHiding: true,
enableSorting: true,
},
Expand Down
3 changes: 2 additions & 1 deletion web/sdk/admin/views/organizations/details/apis/columns.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Text, type DataTableColumnDef } from "@raystack/apsara";
import dayjs from "dayjs";
import { NULL_DATE } from "../../../../utils/constants";
import { DATE_FORMAT } from "~/admin/utils/connect-timestamp";
import styles from "./apis.module.css";
import type {
SearchOrganizationServiceUsersResponse_OrganizationServiceUser,
Expand Down Expand Up @@ -52,7 +53,7 @@ SearchOrganizationServiceUsersResponse_OrganizationServiceUser,
header: "Created on",
cell: ({ getValue }) => {
const value = getValue() as string;
return value !== NULL_DATE ? dayjs(value).format("YYYY-MM-DD") : "-";
return value !== NULL_DATE ? dayjs(value).format(DATE_FORMAT) : "-";
},
enableSorting: true,
enableColumnFilter: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Dialog, Flex, Skeleton, Tabs, Text, toastManager } from "@raystack/apsara";
import styles from "./apis.module.css";
import { useCallback, useEffect, useMemo } from "react";
import dayjs from "dayjs";
import { useQuery } from "@connectrpc/connect-query";
import {
FrontierServiceQueries,
Expand All @@ -10,7 +9,7 @@ import {
type SearchOrganizationServiceUsersResponse_OrganizationServiceUser
} from "@raystack/proton/frontier";
import { create } from "@bufbuild/protobuf";
import { timestampToDayjs } from "../../../../utils/connect-timestamp";
import { formatTimestamp } from "~/admin/utils/connect-timestamp";
import { useTerminology } from "../../../../hooks/useTerminology";

interface ServiceUserDetailsDialogProps {
Expand Down Expand Up @@ -129,7 +128,7 @@ export const ServiceUserDetailsDialog = ({
>
<Text weight="medium">{token.title}</Text>
<Text size="micro">
{timestampToDayjs(token.createdAt)?.format("YYYY-MM-DD")}
{formatTimestamp(token.createdAt)}
</Text>
</Flex>
))}
Expand Down
15 changes: 2 additions & 13 deletions web/sdk/admin/views/organizations/details/invoices/columns.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import styles from "./invoices.module.css";
import dayjs from "dayjs";
import { DataTableColumnDef, Link, Amount } from "@raystack/apsara";
import type {
SearchOrganizationInvoicesResponse_OrganizationInvoice,
} from "@raystack/proton/frontier";
import {
isNullTimestamp,
TimeStamp,
timestampToDate,
} from "../../../../utils/connect-timestamp";
import { formatTimestamp, TimeStamp } from "~/admin/utils/connect-timestamp";

// https://docs.stripe.com/invoicing/overview#invoice-statuses
const InvoiceStatusesMap = {
Expand Down Expand Up @@ -38,13 +33,7 @@ export const getColumns = ({
cell: styles["first-column"],
header: styles["first-column"],
},
cell: ({ getValue }) => {
const value = getValue() as TimeStamp;
const date = isNullTimestamp(value)
? "-"
: dayjs(timestampToDate(value)).format("YYYY-MM-DD");
return date;
},
cell: ({ getValue }) => formatTimestamp(getValue() as TimeStamp),
enableSorting: true,
enableColumnFilter: true,
filterType: "date",
Expand Down
17 changes: 4 additions & 13 deletions web/sdk/admin/views/organizations/details/members/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,9 @@ import type {
} from "@raystack/proton/frontier";
import type { UpdateRolePayload } from "./update-role";
import styles from "./members.module.css";
import dayjs from "dayjs";
import { DotsHorizontalIcon, UpdateIcon } from "@radix-ui/react-icons";
import { DeleteIcon } from "~/admin/assets/icons/DeleteIcon";
import {
isNullTimestamp,
TimeStamp,
timestampToDate,
} from "../../../../utils/connect-timestamp";
import { formatTimestamp, TimeStamp } from "~/admin/utils/connect-timestamp";

const MemberStates = {
enabled: "Active",
Expand Down Expand Up @@ -122,13 +117,9 @@ export const getColumns = ({
{
accessorKey: "orgJoinedAt",
header: "Joined On",
cell: ({ getValue }) => {
const value = getValue() as TimeStamp;
const date = isNullTimestamp(value)
? "-"
: dayjs(timestampToDate(value)).format("YYYY-MM-DD");
return <Text>{date}</Text>;
},
cell: ({ getValue }) => (
<Text>{formatTimestamp(getValue() as TimeStamp)}</Text>
),
enableSorting: true,
enableHiding: true,
// enableColumnFilter: true,
Expand Down
19 changes: 7 additions & 12 deletions web/sdk/admin/views/organizations/details/pat/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
SearchOrganizationPATsResponse_OrganizationPAT,
} from "@raystack/proton/frontier";
import {
formatTimestamp,
isNullTimestamp,
timestampToDayjs,
} from "~/admin/utils/connect-timestamp";
Expand All @@ -25,8 +26,6 @@ interface GetColumnsOptions {
projectsMap: Record<string, Project>;
}

const DATE_FORMAT = "DD MMM YYYY";

export function getColumns({
projectsMap,
}: GetColumnsOptions): DataTableColumnDef<
Expand Down Expand Up @@ -90,10 +89,9 @@ export function getColumns({
accessorKey: "createdAt",
header: "Created On",
styles: { header: { width: "152px" } },
cell: ({ row }) => {
const date = timestampToDayjs(row.original.createdAt);
return date ? <Text>{date.format(DATE_FORMAT)}</Text> : <Text>-</Text>;
},
cell: ({ row }) => (
<Text>{formatTimestamp(row.original.createdAt)}</Text>
),
enableSorting: true,
enableColumnFilter: true,
filterType: "date",
Expand All @@ -103,12 +101,9 @@ export function getColumns({
accessorKey: "expiresAt",
header: "Expiry Date",
styles: { header: { width: "152px" } },
cell: ({ row }) => {
const expiresAt = row.original.expiresAt;
if (!expiresAt || isNullTimestamp(expiresAt)) return <Text>-</Text>;
const date = timestampToDayjs(expiresAt);
return date ? <Text>{date.format(DATE_FORMAT)}</Text> : <Text>-</Text>;
},
cell: ({ row }) => (
<Text>{formatTimestamp(row.original.expiresAt)}</Text>
),
enableSorting: true,
enableColumnFilter: true,
filterType: "date",
Expand Down
15 changes: 2 additions & 13 deletions web/sdk/admin/views/organizations/details/projects/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,7 @@ import type {
} from "@raystack/proton/frontier";
import styles from "./projects.module.css";

import dayjs from "dayjs";
import {
isNullTimestamp,
TimeStamp,
timestampToDate,
} from "../../../../utils/connect-timestamp";
import { formatTimestamp, TimeStamp } from "~/admin/utils/connect-timestamp";
import { DotsHorizontalIcon } from "@radix-ui/react-icons";
import { RenameProjectDialog } from "./rename-project";
import { useState } from "react";
Expand Down Expand Up @@ -276,13 +271,7 @@ export const getColumns = ({
{
accessorKey: "createdAt",
header: "Created On",
cell: ({ getValue }) => {
const value = getValue() as TimeStamp;
const date = isNullTimestamp(value)
? "-"
: dayjs(timestampToDate(value)).format("YYYY-MM-DD");
return date;
},
cell: ({ getValue }) => formatTimestamp(getValue() as TimeStamp),
enableSorting: true,
enableHiding: true,
enableColumnFilter: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import { OrganizationContext } from "../contexts/organization-context";
import { useMutation, useQuery } from "@connectrpc/connect-query";
import { CreateCheckoutRequestSchema, FrontierServiceQueries, GetUpcomingInvoiceRequestSchema } from "@raystack/proton/frontier";
import { create } from "@bufbuild/protobuf";
import { timestampToDayjs } from "../../../../utils/connect-timestamp";
import {
formatTimestamp,
isNullTimestamp,
} from "~/admin/utils/connect-timestamp";

export const BillingDetailsSection = () => {
const { billingAccount, organization } = useContext(OrganizationContext);
Expand Down Expand Up @@ -169,10 +172,10 @@ export const BillingDetailsSection = () => {
<List.Value className={styles["side-panel-section-item-value"]}>
{isLoading ? (
<Skeleton />
) : timestampToDayjs(due_date) ? (
) : !isNullTimestamp(due_date) ? (
<Flex gap={3}>
<CalendarIcon />
<Text>{timestampToDayjs(due_date)?.format("DD MMM YYYY")}</Text>
<Text>{formatTimestamp(due_date)}</Text>
</Flex>
) : (
<Text>-</Text>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { CalendarIcon } from "@radix-ui/react-icons";
import { Flex, List, Text, CopyButton, Tooltip } from "@raystack/apsara";
import styles from "./side-panel.module.css";
import dayjs from "dayjs";
import { useContext } from "react";
import { OrganizationContext } from "../contexts/organization-context";
import type { Organization } from "@raystack/proton/frontier";
import { timestampToDate } from "../../../../utils/connect-timestamp";
import { formatTimestamp } from "~/admin/utils/connect-timestamp";

interface OrganizationDetailsSectionProps {
organization: Organization;
Expand Down Expand Up @@ -61,11 +60,7 @@ export const OrganizationDetailsSection = ({
<List.Value>
<Flex gap={3}>
<CalendarIcon />
<Text>
{dayjs(timestampToDate(organization.createdAt)).format(
"DD MMM YYYY",
)}
</Text>
<Text>{formatTimestamp(organization.createdAt)}</Text>
</Flex>
</List.Value>
</List.Item>
Expand Down
Loading
Loading