OSAGI

Sessions List

Component

About

Active sessions and devices: this device first, browser, system, place and last activity, sign out one session or all others behind a confirmation, busy and error states. From the Auth & Access Kit → ai.osagi.finance/kits/auth-access

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Sessions List to your project and fits it to your theme.

Code

How Sessions List is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

"use client";

import { useCallback, useMemo } from "react";
import {
  type DeviceSession,
  SessionsList,
} from "@/components/ui/sessions-list";

const settings = {
  failRevoke: false,
  latencyMs: 500,
  readOnly: false,
};

const MINUTE = 60_000;

const wait = (ms: number) =>
  new Promise<void>((resolve) => {
    setTimeout(resolve, ms);
  });

/** Four sessions, this device first: sign one out or all the others; `failRevoke` shows a failure. */
export default function Demo(props: Partial<typeof settings>) {
  const { failRevoke, latencyMs, readOnly } = { ...settings, ...props };
  const sessions = useMemo<DeviceSession[]>(() => {
    const now = Date.now();
    const ago = (minutes: number) =>
      new Date(now - minutes * MINUTE).toISOString();
    return [
      {
        browser: "Safari",
        device: "phone",
        id: "s-phone",
        ip: "198.51.100.24",
        lastActive: ago(42),
        location: "Lisbon, Portugal",
        os: "iOS 19",
      },
      {
        browser: "Chrome",
        current: true,
        device: "desktop",
        id: "s-this",
        ip: "203.0.113.7",
        lastActive: ago(0),
        location: "Lisbon, Portugal",
        os: "macOS",
      },
      {
        browser: "Firefox",
        device: "desktop",
        id: "s-office",
        ip: "192.0.2.15",
        lastActive: ago(60 * 26),
        location: "Berlin, Germany",
        os: "Windows 11",
      },
      {
        browser: "Chrome",
        device: "tablet",
        id: "s-tablet",
        lastActive: ago(60 * 24 * 6),
        location: "Porto, Portugal",
        os: "Android 16",
      },
    ];
  }, []);

  const fake = useCallback(async () => {
    await wait(latencyMs);
    if (failRevoke) {
      throw new Error(
        "The server did not answer. Nothing was signed out: try again."
      );
    }
  }, [failRevoke, latencyMs]);

  return (
    <div className="flex min-h-[520px] w-full items-start justify-center bg-background p-6">
      <div className="w-full max-w-2xl">
        <SessionsList
          onRevoke={readOnly ? undefined : fake}
          onRevokeOthers={readOnly ? undefined : fake}
          sessions={sessions}
        />
      </div>
    </div>
  );
}

Dependencies

More by OSAGI

View all
  • AI Orb

    AI Orb

    83
  • KPI Tile

    KPI Tile

    28
  • OTP Input

    OTP Input

    12
  • Reasoning Thread

    Reasoning Thread

    8
  • Assistant Composer

    Assistant Composer

    8
  • Release Notes

    Release Notes

  • Docs TOC

    Docs TOC

  • Docs Search

    Docs Search