- DESIGN_TOKENS.md: Complete rewrite to document --sumi-* token system - APP_SHELL.md: Update layout shell docs (glass bg, backdrop-blur, z-index) - DESIGN_DIRECTION.md: Update aesthetic direction to SUMI philosophy - .storybook/preview.tsx: Remove deleted CSS imports, update bg colors - eslint.config.js: Update color rule message from Kodo to SUMI tokens - tailwind.config.ts: Fix comment referencing deleted design-tokens.css Co-authored-by: Cursor <cursoragent@cursor.com>
1 line
9.7 KiB
JavaScript
1 line
9.7 KiB
JavaScript
import{a as t,j as s}from"./vendor-react-Dkpvlwai.js";import{C as S}from"./confirmation-dialog-oRC6nIEK.js";import{a as b,p as y,l as N,B as A,L,x as C,C as I,b as E,c as M,f as F,e as O,S as h}from"./index-jE2AGx2y.js";import{m as U,aG as B,ar as $,T as H,n as z,aH as G,aI as Y,ax as q,P as J}from"./vendor-icons-CbmLcMl-.js";import"./vendor-CAoAb3tF.js";import"./vendor-router-4bycex72.js";import"./vendor-tanstack-BoI3DtL9.js";import"./vendor-utils-CDFfoeXY.js";function V(e){const i=e.toLowerCase(),n={deviceType:"unknown",os:"Unknown",browser:"Unknown"};if(i.includes("mobile")||i.includes("android")||i.includes("iphone")?n.deviceType="mobile":i.includes("tablet")||i.includes("ipad")?n.deviceType="tablet":n.deviceType="desktop",i.includes("windows")){n.os="Windows";const a=i.match(/windows nt (\d+\.\d+)/);if(a){const r=a[1];r==="10.0"?n.osVersion="10":r==="6.3"?n.osVersion="8.1":r==="6.2"?n.osVersion="8":r==="6.1"?n.osVersion="7":n.osVersion=r}}else if(i.includes("mac os x")||i.includes("macintosh")){n.os="macOS";const a=i.match(/mac os x (\d+[._]\d+)/);a&&(n.osVersion=a[1].replace("_","."))}else if(i.includes("linux"))n.os="Linux";else if(i.includes("android")){n.os="Android";const a=i.match(/android (\d+\.\d+)/);a&&(n.osVersion=a[1])}else if(i.includes("ios")||i.includes("iphone")||i.includes("ipad")){n.os="iOS";const a=i.match(/os (\d+[._]\d+)/);a&&(n.osVersion=a[1].replace("_","."))}if(i.includes("edg/")){n.browser="Microsoft Edge";const a=i.match(/edg\/(\d+\.\d+)/);a&&(n.browserVersion=a[1])}else if(i.includes("chrome/")&&!i.includes("edg/")){n.browser="Chrome";const a=i.match(/chrome\/(\d+\.\d+)/);a&&(n.browserVersion=a[1])}else if(i.includes("firefox/")){n.browser="Firefox";const a=i.match(/firefox\/(\d+\.\d+)/);a&&(n.browserVersion=a[1])}else if(i.includes("safari/")&&!i.includes("chrome/")){n.browser="Safari";const a=i.match(/version\/(\d+\.\d+)/);a&&(n.browserVersion=a[1])}else if(i.includes("opera/")||i.includes("opr/")){n.browser="Opera";const a=i.match(/(?:opera|opr)\/(\d+\.\d+)/);a&&(n.browserVersion=a[1])}if(i.includes("iphone"))i.match(/iphone\s+os\s+(\d+[._]\d+)/)&&(n.deviceModel="iPhone");else if(i.includes("ipad"))n.deviceModel="iPad";else if(i.includes("android")){const a=i.match(/android.*?;\s*([^)]+)\)/);a&&(n.deviceModel=a[1].trim())}return n}function K(e){const i=[];return e.deviceModel&&i.push(e.deviceModel),i.push(e.os),e.osVersion&&i.push(e.osVersion),i.push(e.browser),e.browserVersion&&i.push(e.browserVersion),i.join(" • ")}function Q(e){if(!e)return"Unknown location";const i=[];return e.city&&i.push(e.city),e.region&&i.push(e.region),e.country&&i.push(e.country),i.length>0?i.join(", "):"Unknown location"}function X(e){return e==="127.0.0.1"||e==="localhost"||e.startsWith("192.168.")||e.startsWith("10.")||e.startsWith("172.16.")||e.startsWith("172.17.")||e.startsWith("172.18.")||e.startsWith("172.19.")||e.startsWith("172.20.")||e.startsWith("172.21.")||e.startsWith("172.22.")||e.startsWith("172.23.")||e.startsWith("172.24.")||e.startsWith("172.25.")||e.startsWith("172.26.")||e.startsWith("172.27.")||e.startsWith("172.28.")||e.startsWith("172.29.")||e.startsWith("172.30.")||e.startsWith("172.31.")}function Z(e){const[i,n]=t.useState(e?.initialSessions??[]),[a,r]=t.useState(e?.isLoading??!0),[g,m]=t.useState(null),[p,j]=t.useState(!1),[w,c]=t.useState(null),[d,f]=t.useState(null),[k,x]=t.useState(!1),o=t.useCallback(async()=>{try{r(!0),c(null);const l=await b.get("/auth/sessions");n(l.data.sessions)}catch(l){const u=y(l);N.error("Failed to fetch sessions",{message:u.message}),c(u.message)}finally{r(!1)}},[]);t.useEffect(()=>{if(e?.initialSessions!==void 0){n(e.initialSessions),r(!1);return}if(e?.isLoading===!0){r(!0);return}o()},[o,e?.initialSessions,e?.isLoading]);const v=t.useCallback(l=>{f(l)},[]),W=t.useCallback(async()=>{if(d)try{m(d),c(null),await b.delete(`/auth/sessions/${d}`),await o(),f(null)}catch(l){const u=y(l);N.error("Failed to revoke session",{message:u.message,sessionId:d}),c(u.message)}finally{m(null)}},[d,o]),_=t.useCallback(()=>{x(!0)},[]),P=t.useCallback(async()=>{try{j(!0),c(null),await b.delete("/auth/sessions"),await o(),x(!1)}catch(l){const u=y(l);N.error("Failed to revoke sessions",{message:u.message}),c(u.message)}finally{j(!1)}},[o]),T=t.useCallback(()=>f(null),[]),D=t.useCallback(()=>x(!1),[]);return{sessions:i,loading:a,error:w,revoking:g,revokingAll:p,sessionToRevoke:d,showRevokeAllDialog:k,fetchSessions:o,handleRevokeClick:v,revokeSession:W,handleRevokeAllClick:_,revokeAllOther:P,closeRevokeDialog:T,closeRevokeAllDialog:D}}function ee(){return s.jsxs("div",{children:[s.jsx("h1",{className:"text-heading-1",children:"Active Sessions"}),s.jsx("p",{className:"text-muted-foreground",children:"Manage your active sessions and sign out from other devices"})]})}function se({message:e}){return s.jsx("div",{className:"bg-destructive/10 text-destructive px-4 py-4 rounded-md",children:e})}function ie({disabled:e,loading:i,onClick:n}){return s.jsx("div",{className:"flex justify-end",children:s.jsx(A,{onClick:n,disabled:e,variant:"destructive",children:i?s.jsxs(s.Fragment,{children:[s.jsx(L,{className:"mr-2 h-4 w-4"}),"Revoking..."]}):s.jsxs(s.Fragment,{children:[s.jsx(U,{className:"mr-2 h-4 w-4"}),"Revoke All Other Sessions"]})})})}function ae(){return s.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"No active sessions found."})}function ne(e){switch(e){case"mobile":return s.jsx(q,{className:"h-5 w-5"});case"tablet":return s.jsx(Y,{className:"h-5 w-5"});case"desktop":return s.jsx(G,{className:"h-5 w-5"});default:return s.jsx(z,{className:"h-5 w-5"})}}function R(e){const i=new Date(e);return new Intl.DateTimeFormat("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}).format(i)}function re({session:e,isRevoking:i,onRevokeClick:n}){const a=e.device_info??V(e.user_agent),r=e.location_info;return s.jsxs("div",{className:`flex items-center justify-between p-4 border rounded-lg ${e.is_current?"border-primary bg-primary/5":"border-border"}`,children:[s.jsxs("div",{className:"flex items-start gap-4 flex-1",children:[s.jsx("div",{className:"mt-1",children:ne(a.deviceType)}),s.jsxs("div",{className:"flex-1 space-y-2",children:[s.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[s.jsx("p",{className:"font-medium",children:K(a)}),e.is_current&&s.jsx(C,{variant:"default",className:"bg-primary text-primary-foreground",children:"Current Session"}),s.jsx(C,{variant:"secondary",className:"capitalize",children:a.deviceType})]}),s.jsxs("div",{className:"flex flex-wrap gap-4 text-sm text-muted-foreground",children:[s.jsxs("div",{className:"flex items-center gap-1",children:[s.jsx(B,{className:"h-4 w-4"}),s.jsx("span",{children:e.ip_address||"Unknown IP"})]}),r&&s.jsxs("div",{className:"flex items-center gap-1",children:[s.jsx($,{className:"h-4 w-4"}),s.jsx("span",{children:Q(r)})]}),s.jsxs("div",{children:[s.jsx("span",{className:"font-medium",children:"Created:"})," ",R(e.created_at)]}),e.last_activity&&s.jsxs("div",{children:[s.jsx("span",{className:"font-medium",children:"Last activity:"})," ",R(e.last_activity)]})]}),a.browserVersion&&s.jsxs("div",{className:"text-xs text-muted-foreground",children:[a.browser," ",a.browserVersion,a.osVersion&&` • ${a.os} ${a.osVersion}`]})]})]}),!e.is_current&&s.jsx(A,{onClick:()=>n(e.id),disabled:i,variant:"destructive",size:"sm",children:i?s.jsxs(s.Fragment,{children:[s.jsx(L,{className:"mr-2 h-4 w-4"}),"Revoking..."]}):s.jsxs(s.Fragment,{children:[s.jsx(H,{className:"mr-2 h-4 w-4"}),"Revoke"]})})]})}function te({sessions:e,revoking:i,onRevokeClick:n}){return s.jsxs(I,{children:[s.jsxs(E,{children:[s.jsxs(M,{className:"flex items-center gap-2",children:[s.jsx(J,{className:"h-5 w-5"}),"Sessions (",e.length,")"]}),s.jsx(F,{children:"These are the devices where you're currently signed in"})]}),s.jsx(O,{children:e.length===0?s.jsx(ae,{}):s.jsx("div",{className:"space-y-4",children:e.map(a=>s.jsx(re,{session:a,isRevoking:i===a.id,onRevokeClick:n},a.id))})})]})}function oe(){return s.jsx("div",{className:"flex items-center justify-center min-h-layout-page-sm",children:s.jsxs("div",{className:"space-y-6 w-full max-w-2xl",children:[s.jsx(h,{className:"h-8 w-64 rounded"}),s.jsx(h,{className:"h-4 w-96 rounded"}),s.jsx("div",{className:"flex justify-end",children:s.jsx(h,{className:"h-10 w-56 rounded"})}),s.jsxs("div",{className:"rounded-lg border bg-card p-6 space-y-4",children:[s.jsx(h,{className:"h-6 w-32 rounded"}),s.jsx(h,{className:"h-4 w-72 rounded"}),s.jsxs("div",{className:"space-y-4 pt-4",children:[s.jsx(h,{className:"h-24 rounded-lg"}),s.jsx(h,{className:"h-24 rounded-lg"})]})]})]})})}function ve(e){const i=e?{initialSessions:e.initialSessions,isLoading:e.isLoading}:void 0,{sessions:n,loading:a,error:r,revoking:g,revokingAll:m,sessionToRevoke:p,showRevokeAllDialog:j,handleRevokeClick:w,revokeSession:c,handleRevokeAllClick:d,revokeAllOther:f,closeRevokeDialog:k,closeRevokeAllDialog:x}=Z(i),o=t.useMemo(()=>n.map(v=>({...v,device_info:V(v.user_agent),location_info:X(v.ip_address)?{country:"Local",region:"Network",city:"Private IP"}:null})),[n]);return a?s.jsx(oe,{}):s.jsxs("div",{className:"space-y-6",children:[s.jsx(ee,{}),r&&s.jsx(se,{message:r}),s.jsx(ie,{disabled:m||n.length<=1,loading:m,onClick:d}),s.jsx(te,{sessions:o,revoking:g,onRevokeClick:w}),s.jsx(S,{open:!!p,onClose:k,onConfirm:c,title:"Revoke Session",description:"Are you sure you want to revoke this session? The user will be logged out from this device.",confirmLabel:"Revoke",cancelLabel:"Cancel",variant:"destructive",isLoading:!!g}),s.jsx(S,{open:j,onClose:x,onConfirm:f,title:"Revoke All Other Sessions",description:"Are you sure you want to revoke all other sessions? You will remain logged in on this device, but all other devices will be logged out.",confirmLabel:"Revoke All",cancelLabel:"Cancel",variant:"destructive",isLoading:m})]})}export{ve as SessionsPage,ve as default};
|