deepspace 0.4.3 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4954,6 +4954,236 @@ var integration = {
4954
4954
  }
4955
4955
  };
4956
4956
 
4957
+ // src/client/voice/useVoiceAgent.ts
4958
+ import { useCallback as useCallback26, useEffect as useEffect20, useRef as useRef17, useState as useState17 } from "react";
4959
+ var OPENAI_REALTIME_BASE = "https://api.openai.com/v1";
4960
+ var ZERO_USAGE = { inputAudioTokens: 0, outputAudioTokens: 0, inputTextTokens: 0, outputTextTokens: 0 };
4961
+ function useVoiceAgent(options = {}) {
4962
+ const [status, setStatus] = useState17("idle");
4963
+ const [isMuted, setIsMuted] = useState17(false);
4964
+ const [isAgentSpeaking, setIsAgentSpeaking] = useState17(false);
4965
+ const [transcript, setTranscript] = useState17([]);
4966
+ const [error, setError] = useState17(null);
4967
+ const pcRef = useRef17(null);
4968
+ const dcRef = useRef17(null);
4969
+ const streamRef = useRef17(null);
4970
+ const audioRef = useRef17(null);
4971
+ const timerRef = useRef17(null);
4972
+ const sessionIdRef = useRef17(null);
4973
+ const liveStartRef = useRef17(null);
4974
+ const settledRef = useRef17(false);
4975
+ const usageRef = useRef17({ ...ZERO_USAGE });
4976
+ const optsRef = useRef17(options);
4977
+ optsRef.current = options;
4978
+ const settle = useCallback26(async () => {
4979
+ const sessionId = sessionIdRef.current;
4980
+ if (!sessionId || settledRef.current) return;
4981
+ settledRef.current = true;
4982
+ const durationSeconds = liveStartRef.current ? Math.max(0, (Date.now() - liveStartRef.current) / 1e3) : 0;
4983
+ try {
4984
+ await integration.post("openai-realtime/settle-session", {
4985
+ sessionId,
4986
+ durationSeconds,
4987
+ usage: usageRef.current
4988
+ });
4989
+ } catch {
4990
+ }
4991
+ }, []);
4992
+ const cleanup = useCallback26(() => {
4993
+ if (timerRef.current) {
4994
+ clearTimeout(timerRef.current);
4995
+ timerRef.current = null;
4996
+ }
4997
+ try {
4998
+ dcRef.current?.close();
4999
+ } catch {
5000
+ }
5001
+ try {
5002
+ streamRef.current?.getTracks().forEach((t) => t.stop());
5003
+ } catch {
5004
+ }
5005
+ try {
5006
+ if (pcRef.current) pcRef.current.onconnectionstatechange = null;
5007
+ pcRef.current?.close();
5008
+ } catch {
5009
+ }
5010
+ if (audioRef.current) audioRef.current.srcObject = null;
5011
+ dcRef.current = null;
5012
+ pcRef.current = null;
5013
+ streamRef.current = null;
5014
+ audioRef.current = null;
5015
+ }, []);
5016
+ const stop = useCallback26(async () => {
5017
+ cleanup();
5018
+ await settle();
5019
+ setIsAgentSpeaking(false);
5020
+ setStatus((s) => s === "error" ? s : "ended");
5021
+ }, [cleanup, settle]);
5022
+ const appendTranscript = useCallback26((role, delta) => {
5023
+ if (!delta) return;
5024
+ setTranscript((prev) => {
5025
+ const last = prev[prev.length - 1];
5026
+ if (last && last.role === role) return [...prev.slice(0, -1), { role, content: last.content + delta }];
5027
+ return [...prev, { role, content: delta }];
5028
+ });
5029
+ }, []);
5030
+ const handleToolCall = useCallback26(async (item) => {
5031
+ const onToolCall = optsRef.current.onToolCall;
5032
+ let output = null;
5033
+ if (onToolCall && item.name) {
5034
+ let args = {};
5035
+ try {
5036
+ args = item.arguments ? JSON.parse(item.arguments) : {};
5037
+ } catch {
5038
+ args = {};
5039
+ }
5040
+ try {
5041
+ output = await onToolCall(item.name, args);
5042
+ } catch (e) {
5043
+ output = { error: e instanceof Error ? e.message : String(e) };
5044
+ }
5045
+ }
5046
+ const dc = dcRef.current;
5047
+ if (!dc || dc.readyState !== "open") return;
5048
+ dc.send(
5049
+ JSON.stringify({
5050
+ type: "conversation.item.create",
5051
+ item: { type: "function_call_output", call_id: item.call_id, output: JSON.stringify(output ?? null) }
5052
+ })
5053
+ );
5054
+ dc.send(JSON.stringify({ type: "response.create" }));
5055
+ }, []);
5056
+ const handleEvent = useCallback26(
5057
+ (raw) => {
5058
+ if (typeof raw !== "string") return;
5059
+ let ev;
5060
+ try {
5061
+ ev = JSON.parse(raw);
5062
+ } catch {
5063
+ return;
5064
+ }
5065
+ switch (ev.type) {
5066
+ case "response.output_audio_transcript.delta":
5067
+ case "response.audio_transcript.delta":
5068
+ appendTranscript("assistant", ev.delta ?? "");
5069
+ break;
5070
+ case "conversation.item.input_audio_transcription.completed":
5071
+ appendTranscript("user", ev.transcript ?? "");
5072
+ break;
5073
+ case "output_audio_buffer.started":
5074
+ setIsAgentSpeaking(true);
5075
+ break;
5076
+ case "output_audio_buffer.stopped":
5077
+ setIsAgentSpeaking(false);
5078
+ break;
5079
+ case "response.done": {
5080
+ const u = ev.response?.usage;
5081
+ if (u) {
5082
+ usageRef.current.inputAudioTokens += u.input_token_details?.audio_tokens ?? 0;
5083
+ usageRef.current.outputAudioTokens += u.output_token_details?.audio_tokens ?? 0;
5084
+ usageRef.current.inputTextTokens += u.input_token_details?.text_tokens ?? 0;
5085
+ usageRef.current.outputTextTokens += u.output_token_details?.text_tokens ?? 0;
5086
+ }
5087
+ for (const item of ev.response?.output ?? []) {
5088
+ if (item?.type === "function_call") void handleToolCall(item);
5089
+ }
5090
+ break;
5091
+ }
5092
+ }
5093
+ },
5094
+ [appendTranscript, handleToolCall]
5095
+ );
5096
+ const start = useCallback26(
5097
+ async (overrides = {}) => {
5098
+ if (sessionIdRef.current) {
5099
+ cleanup();
5100
+ await settle();
5101
+ }
5102
+ const o = { ...optsRef.current, ...overrides };
5103
+ setError(null);
5104
+ setTranscript([]);
5105
+ setIsAgentSpeaking(false);
5106
+ setStatus("connecting");
5107
+ settledRef.current = false;
5108
+ liveStartRef.current = null;
5109
+ sessionIdRef.current = null;
5110
+ usageRef.current = { ...ZERO_USAGE };
5111
+ try {
5112
+ const res = await integration.post(
5113
+ "openai-realtime/create-session",
5114
+ { instructions: o.instructions, voice: o.voice, tools: o.tools, maxMinutes: o.maxMinutes }
5115
+ );
5116
+ if (!res.success || !res.data) throw new Error(res.error ?? "Failed to start voice session");
5117
+ const { sessionId, clientSecret, model, maxMinutes } = res.data;
5118
+ sessionIdRef.current = sessionId;
5119
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
5120
+ streamRef.current = stream;
5121
+ const pc = new RTCPeerConnection();
5122
+ pcRef.current = pc;
5123
+ pc.onconnectionstatechange = () => {
5124
+ if (pc.connectionState === "failed" || pc.connectionState === "closed") void stop();
5125
+ };
5126
+ const audio = new Audio();
5127
+ audio.autoplay = true;
5128
+ audioRef.current = audio;
5129
+ pc.ontrack = (e) => {
5130
+ audio.srcObject = e.streams[0];
5131
+ };
5132
+ stream.getTracks().forEach((t) => pc.addTrack(t, stream));
5133
+ const dc = pc.createDataChannel("oai-events");
5134
+ dcRef.current = dc;
5135
+ dc.onmessage = (e) => handleEvent(e.data);
5136
+ const offer = await pc.createOffer();
5137
+ await pc.setLocalDescription(offer);
5138
+ const sdpRes = await fetch(`${OPENAI_REALTIME_BASE}/realtime/calls?model=${encodeURIComponent(model)}`, {
5139
+ method: "POST",
5140
+ headers: { Authorization: `Bearer ${clientSecret}`, "Content-Type": "application/sdp" },
5141
+ body: offer.sdp
5142
+ });
5143
+ if (!sdpRes.ok) throw new Error(`Realtime connect failed (${sdpRes.status})`);
5144
+ const answer = await sdpRes.text();
5145
+ await pc.setRemoteDescription({ type: "answer", sdp: answer });
5146
+ liveStartRef.current = Date.now();
5147
+ setStatus("live");
5148
+ timerRef.current = setTimeout(() => void stop(), (maxMinutes ?? 30) * 6e4);
5149
+ } catch (err) {
5150
+ setError(err instanceof Error ? err.message : String(err));
5151
+ setStatus("error");
5152
+ cleanup();
5153
+ await settle();
5154
+ }
5155
+ },
5156
+ [cleanup, settle, stop, handleEvent]
5157
+ );
5158
+ const toggleMute = useCallback26(() => {
5159
+ const stream = streamRef.current;
5160
+ if (!stream) return;
5161
+ setIsMuted((muted) => {
5162
+ const next = !muted;
5163
+ stream.getAudioTracks().forEach((t) => t.enabled = !next);
5164
+ return next;
5165
+ });
5166
+ }, []);
5167
+ useEffect20(() => {
5168
+ return () => {
5169
+ cleanup();
5170
+ void settle();
5171
+ };
5172
+ }, [cleanup, settle]);
5173
+ return {
5174
+ status,
5175
+ start,
5176
+ stop,
5177
+ isMuted,
5178
+ toggleMute,
5179
+ isAgentSpeaking,
5180
+ transcript,
5181
+ error,
5182
+ pc: pcRef.current,
5183
+ dataChannel: dcRef.current
5184
+ };
5185
+ }
5186
+
4957
5187
  // src/client/ai-stream.ts
4958
5188
  function parseSseLine(line) {
4959
5189
  if (!line) return null;
@@ -5022,7 +5252,7 @@ function decodeAiStreamChunk(chunk) {
5022
5252
  }
5023
5253
 
5024
5254
  // src/client/status.ts
5025
- import { useCallback as useCallback26, useEffect as useEffect20, useMemo as useMemo15, useRef as useRef17, useState as useState17 } from "react";
5255
+ import { useCallback as useCallback27, useEffect as useEffect21, useMemo as useMemo15, useRef as useRef18, useState as useState18 } from "react";
5026
5256
 
5027
5257
  // src/client/status-core.ts
5028
5258
  var ASYNC_RESOURCE_DEFAULTS = {
@@ -5107,7 +5337,7 @@ function useAsyncResource(fetcher, deps, options = {}) {
5107
5337
  const retry = options.retry ?? ASYNC_RESOURCE_DEFAULTS.retry;
5108
5338
  const retryDelayMs = options.retryDelayMs ?? ASYNC_RESOURCE_DEFAULTS.retryDelayMs;
5109
5339
  const slowAfterMs = options.slowAfterMs ?? ASYNC_RESOURCE_DEFAULTS.slowAfterMs;
5110
- const [state, setState] = useState17(() => ({
5340
+ const [state, setState] = useState18(() => ({
5111
5341
  status: enabled ? "loading" : "idle",
5112
5342
  data: options.initialData ?? null,
5113
5343
  error: null,
@@ -5115,12 +5345,12 @@ function useAsyncResource(fetcher, deps, options = {}) {
5115
5345
  isSlow: false,
5116
5346
  retryCount: 0
5117
5347
  }));
5118
- const requestIdRef = useRef17(0);
5119
- const [reloadTick, setReloadTick] = useState17(0);
5120
- const reload = useCallback26(() => {
5348
+ const requestIdRef = useRef18(0);
5349
+ const [reloadTick, setReloadTick] = useState18(0);
5350
+ const reload = useCallback27(() => {
5121
5351
  setReloadTick((tick) => tick + 1);
5122
5352
  }, []);
5123
- useEffect20(() => {
5353
+ useEffect21(() => {
5124
5354
  if (!enabled) {
5125
5355
  setState((prev) => ({ ...prev, status: "idle", isRefreshing: false, isSlow: false, retryCount: 0 }));
5126
5356
  return;
@@ -5209,7 +5439,7 @@ function usePagedResource(fetchPage, deps, options = {}) {
5209
5439
  const retryDelayMs = options.retryDelayMs ?? ASYNC_RESOURCE_DEFAULTS.retryDelayMs;
5210
5440
  const maxRetryDelayMs = options.maxRetryDelayMs ?? 3e4;
5211
5441
  const hasInitialItems = initialItems.length > 0;
5212
- const [state, setState] = useState17(() => ({
5442
+ const [state, setState] = useState18(() => ({
5213
5443
  status: enabled ? hasInitialItems ? "ready" : "loading" : "idle",
5214
5444
  items: initialItems,
5215
5445
  error: null,
@@ -5219,25 +5449,25 @@ function usePagedResource(fetchPage, deps, options = {}) {
5219
5449
  isLoadingMore: false,
5220
5450
  isRefreshing: false
5221
5451
  }));
5222
- const requestIdRef = useRef17(0);
5223
- const controllerRef = useRef17(null);
5224
- const loadingRef = useRef17(false);
5225
- const nextPageRef = useRef17(hasInitialItems ? 2 : 1);
5226
- const failedPageRef = useRef17(null);
5227
- const failureCountRef = useRef17(0);
5228
- const cooldownUntilRef = useRef17(0);
5229
- const autoRetryTimerRef = useRef17(null);
5230
- const clearAutoRetryTimer = useCallback26(() => {
5452
+ const requestIdRef = useRef18(0);
5453
+ const controllerRef = useRef18(null);
5454
+ const loadingRef = useRef18(false);
5455
+ const nextPageRef = useRef18(hasInitialItems ? 2 : 1);
5456
+ const failedPageRef = useRef18(null);
5457
+ const failureCountRef = useRef18(0);
5458
+ const cooldownUntilRef = useRef18(0);
5459
+ const autoRetryTimerRef = useRef18(null);
5460
+ const clearAutoRetryTimer = useCallback27(() => {
5231
5461
  if (autoRetryTimerRef.current) {
5232
5462
  clearTimeout(autoRetryTimerRef.current);
5233
5463
  autoRetryTimerRef.current = null;
5234
5464
  }
5235
5465
  }, []);
5236
- const resetCooldown = useCallback26(() => {
5466
+ const resetCooldown = useCallback27(() => {
5237
5467
  failureCountRef.current = 0;
5238
5468
  cooldownUntilRef.current = 0;
5239
5469
  }, []);
5240
- const setFailureCooldown = useCallback26(() => {
5470
+ const setFailureCooldown = useCallback27(() => {
5241
5471
  failureCountRef.current += 1;
5242
5472
  const delay = getPagedResourceCooldownMs({
5243
5473
  failureCount: failureCountRef.current,
@@ -5247,7 +5477,7 @@ function usePagedResource(fetchPage, deps, options = {}) {
5247
5477
  cooldownUntilRef.current = Date.now() + delay;
5248
5478
  return delay;
5249
5479
  }, [maxRetryDelayMs, retryDelayMs]);
5250
- const startLoad = useCallback26(async (page, mode) => {
5480
+ const startLoad = useCallback27(async (page, mode) => {
5251
5481
  if (!enabled || loadingRef.current) return;
5252
5482
  if (mode === "auto" && !canAutoLoadPagedResource({
5253
5483
  hasMore: true,
@@ -5327,21 +5557,21 @@ function usePagedResource(fetchPage, deps, options = {}) {
5327
5557
  }
5328
5558
  }
5329
5559
  }, [autoRetryOnError, clearAutoRetryTimer, enabled, fetchPage, keepPreviousData, pageSize, resetCooldown, setFailureCooldown]);
5330
- const loadMore = useCallback26(() => {
5560
+ const loadMore = useCallback27(() => {
5331
5561
  if (!state.hasMore || state.isLoadingInitial || state.isLoadingMore || state.isRefreshing) return;
5332
5562
  void startLoad(nextPageRef.current, "auto");
5333
5563
  }, [startLoad, state.hasMore, state.isLoadingInitial, state.isLoadingMore, state.isRefreshing]);
5334
- const retry = useCallback26(() => {
5564
+ const retry = useCallback27(() => {
5335
5565
  const page = failedPageRef.current ?? nextPageRef.current;
5336
5566
  void startLoad(page, "manual");
5337
5567
  }, [startLoad]);
5338
- const refresh = useCallback26(() => {
5568
+ const refresh = useCallback27(() => {
5339
5569
  failedPageRef.current = null;
5340
5570
  resetCooldown();
5341
5571
  nextPageRef.current = 1;
5342
5572
  void startLoad(1, "refresh");
5343
5573
  }, [resetCooldown, startLoad]);
5344
- useEffect20(() => {
5574
+ useEffect21(() => {
5345
5575
  requestIdRef.current += 1;
5346
5576
  controllerRef.current?.abort();
5347
5577
  clearAutoRetryTimer();
@@ -5378,7 +5608,7 @@ function usePagedResource(fetchPage, deps, options = {}) {
5378
5608
  }
5379
5609
 
5380
5610
  // src/client/subscriptions/useSubscription.ts
5381
- import { useCallback as useCallback27, useEffect as useEffect21, useState as useState18 } from "react";
5611
+ import { useCallback as useCallback28, useEffect as useEffect22, useState as useState19 } from "react";
5382
5612
 
5383
5613
  // src/shared/subscription.ts
5384
5614
  var ENTITLED_STATUSES = /* @__PURE__ */ new Set([
@@ -5409,7 +5639,7 @@ async function authedJson(path, init) {
5409
5639
  return data;
5410
5640
  }
5411
5641
  function useSubscription() {
5412
- const [state, setState] = useState18({
5642
+ const [state, setState] = useState19({
5413
5643
  tier: "free",
5414
5644
  status: "none",
5415
5645
  interval: null,
@@ -5418,9 +5648,9 @@ function useSubscription() {
5418
5648
  trialEndsAt: null,
5419
5649
  plans: []
5420
5650
  });
5421
- const [isLoading, setLoading] = useState18(true);
5422
- const [error, setError] = useState18(null);
5423
- const refresh = useCallback27(async () => {
5651
+ const [isLoading, setLoading] = useState19(true);
5652
+ const [error, setError] = useState19(null);
5653
+ const refresh = useCallback28(async () => {
5424
5654
  setLoading(true);
5425
5655
  try {
5426
5656
  const r = await authedJson("/_deepspace/subscriptions/me");
@@ -5440,15 +5670,15 @@ function useSubscription() {
5440
5670
  setLoading(false);
5441
5671
  }
5442
5672
  }, []);
5443
- useEffect21(() => {
5673
+ useEffect22(() => {
5444
5674
  refresh();
5445
5675
  }, [refresh]);
5446
5676
  const entitled = isEntitled(state.tier, state.status);
5447
- const hasTier = useCallback27(
5677
+ const hasTier = useCallback28(
5448
5678
  (slug) => state.tier === slug && isEntitled(state.tier, state.status),
5449
5679
  [state.tier, state.status]
5450
5680
  );
5451
- const isAtLeast = useCallback27(
5681
+ const isAtLeast = useCallback28(
5452
5682
  (slug) => {
5453
5683
  if (!isEntitled(state.tier, state.status)) return false;
5454
5684
  const targetRank = state.plans.find((p) => p.slug === slug)?.rank;
@@ -5458,7 +5688,7 @@ function useSubscription() {
5458
5688
  },
5459
5689
  [state.plans, state.tier, state.status]
5460
5690
  );
5461
- const subscribe = useCallback27(
5691
+ const subscribe = useCallback28(
5462
5692
  async (planSlug, opts) => {
5463
5693
  const result = await authedJson("/_deepspace/subscriptions/checkout", {
5464
5694
  method: "POST",
@@ -5478,7 +5708,7 @@ function useSubscription() {
5478
5708
  },
5479
5709
  [refresh]
5480
5710
  );
5481
- const openPortal = useCallback27(
5711
+ const openPortal = useCallback28(
5482
5712
  async (returnUrl) => {
5483
5713
  return authedJson("/_deepspace/subscriptions/portal", {
5484
5714
  method: "POST",
@@ -5547,7 +5777,7 @@ function PricingTable(props) {
5547
5777
  }
5548
5778
 
5549
5779
  // src/client/charges/useCheckout.ts
5550
- import { useCallback as useCallback28, useEffect as useEffect22, useMemo as useMemo16, useState as useState19 } from "react";
5780
+ import { useCallback as useCallback29, useEffect as useEffect23, useMemo as useMemo16, useState as useState20 } from "react";
5551
5781
  async function authedJson2(path, init) {
5552
5782
  const token = await getAuthToken();
5553
5783
  const res = await fetch(path, {
@@ -5566,10 +5796,10 @@ async function authedJson2(path, init) {
5566
5796
  return data;
5567
5797
  }
5568
5798
  function useCheckout(opts) {
5569
- const [purchases, setPurchases] = useState19([]);
5570
- const [isLoading, setLoading] = useState19(true);
5571
- const [error, setError] = useState19(null);
5572
- const refresh = useCallback28(async () => {
5799
+ const [purchases, setPurchases] = useState20([]);
5800
+ const [isLoading, setLoading] = useState20(true);
5801
+ const [error, setError] = useState20(null);
5802
+ const refresh = useCallback29(async () => {
5573
5803
  setLoading(true);
5574
5804
  try {
5575
5805
  const r = await authedJson2(
@@ -5583,10 +5813,10 @@ function useCheckout(opts) {
5583
5813
  setLoading(false);
5584
5814
  }
5585
5815
  }, []);
5586
- useEffect22(() => {
5816
+ useEffect23(() => {
5587
5817
  refresh();
5588
5818
  }, [refresh]);
5589
- const chargeOnce = useCallback28(
5819
+ const chargeOnce = useCallback29(
5590
5820
  async (chargeOpts) => {
5591
5821
  setError(null);
5592
5822
  const common = {
@@ -5620,7 +5850,7 @@ function useCheckout(opts) {
5620
5850
  },
5621
5851
  []
5622
5852
  );
5623
- const ownsProduct = useCallback28(
5853
+ const ownsProduct = useCallback29(
5624
5854
  (productId) => purchases.some((p) => p.productId === productId),
5625
5855
  [purchases]
5626
5856
  );
@@ -5638,1622 +5868,17 @@ function useCheckout(opts) {
5638
5868
  refresh
5639
5869
  };
5640
5870
  }
5641
-
5642
- // src/ui/utils.ts
5643
- import { clsx } from "clsx";
5644
- import { twMerge } from "tailwind-merge";
5645
- function cn(...inputs) {
5646
- return twMerge(clsx(inputs));
5647
- }
5648
-
5649
- // src/ui/Card.tsx
5650
- import * as React7 from "react";
5651
- import { jsx as jsx11 } from "react/jsx-runtime";
5652
- var Card = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(
5653
- "div",
5654
- {
5655
- ref,
5656
- className: cn(
5657
- "relative rounded-2xl border border-border bg-card text-card-foreground shadow-card",
5658
- className
5659
- ),
5660
- ...props
5661
- }
5662
- ));
5663
- Card.displayName = "Card";
5664
- var CardHeader = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(
5665
- "div",
5666
- {
5667
- ref,
5668
- className: cn("flex flex-col space-y-1.5 p-4 sm:p-6", className),
5669
- ...props
5670
- }
5671
- ));
5672
- CardHeader.displayName = "CardHeader";
5673
- var CardTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(
5674
- "div",
5675
- {
5676
- ref,
5677
- className: cn("font-semibold leading-none tracking-tight", className),
5678
- ...props
5679
- }
5680
- ));
5681
- CardTitle.displayName = "CardTitle";
5682
- var CardDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(
5683
- "div",
5684
- {
5685
- ref,
5686
- className: cn("text-sm text-muted-foreground", className),
5687
- ...props
5688
- }
5689
- ));
5690
- CardDescription.displayName = "CardDescription";
5691
- var CardContent = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx11("div", { ref, className: cn("p-4 pt-0 sm:p-6 sm:pt-0", className), ...props }));
5692
- CardContent.displayName = "CardContent";
5693
- var CardFooter = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(
5694
- "div",
5695
- {
5696
- ref,
5697
- className: cn("flex items-center p-4 pt-0 sm:p-6 sm:pt-0", className),
5698
- ...props
5699
- }
5700
- ));
5701
- CardFooter.displayName = "CardFooter";
5702
-
5703
- // src/ui/Separator.tsx
5704
- import * as React8 from "react";
5705
- import * as SeparatorPrimitive from "@radix-ui/react-separator";
5706
- import { jsx as jsx12 } from "react/jsx-runtime";
5707
- var Separator = React8.forwardRef(
5708
- ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx12(
5709
- SeparatorPrimitive.Root,
5710
- {
5711
- ref,
5712
- decorative,
5713
- orientation,
5714
- className: cn(
5715
- "shrink-0 bg-border",
5716
- orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
5717
- className
5718
- ),
5719
- ...props
5720
- }
5721
- )
5722
- );
5723
- Separator.displayName = SeparatorPrimitive.Root.displayName;
5724
-
5725
- // src/ui/Table.tsx
5726
- import * as React9 from "react";
5727
- import { jsx as jsx13 } from "react/jsx-runtime";
5728
- var Table = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx13("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ jsx13(
5729
- "table",
5730
- {
5731
- ref,
5732
- className: cn("w-full caption-bottom text-sm", className),
5733
- ...props
5734
- }
5735
- ) }));
5736
- Table.displayName = "Table";
5737
- var TableHeader = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx13("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
5738
- TableHeader.displayName = "TableHeader";
5739
- var TableBody = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx13(
5740
- "tbody",
5741
- {
5742
- ref,
5743
- className: cn("[&_tr:last-child]:border-0", className),
5744
- ...props
5745
- }
5746
- ));
5747
- TableBody.displayName = "TableBody";
5748
- var TableFooter = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx13(
5749
- "tfoot",
5750
- {
5751
- ref,
5752
- className: cn(
5753
- "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
5754
- className
5755
- ),
5756
- ...props
5757
- }
5758
- ));
5759
- TableFooter.displayName = "TableFooter";
5760
- var TableRow = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx13(
5761
- "tr",
5762
- {
5763
- ref,
5764
- className: cn(
5765
- "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
5766
- className
5767
- ),
5768
- ...props
5769
- }
5770
- ));
5771
- TableRow.displayName = "TableRow";
5772
- var TableHead = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx13(
5773
- "th",
5774
- {
5775
- ref,
5776
- className: cn(
5777
- "h-10 px-2 sm:px-3 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
5778
- className
5779
- ),
5780
- ...props
5781
- }
5782
- ));
5783
- TableHead.displayName = "TableHead";
5784
- var TableCell = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx13(
5785
- "td",
5786
- {
5787
- ref,
5788
- className: cn(
5789
- "p-2 sm:p-3 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
5790
- className
5791
- ),
5792
- ...props
5793
- }
5794
- ));
5795
- TableCell.displayName = "TableCell";
5796
- var TableCaption = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx13(
5797
- "caption",
5798
- {
5799
- ref,
5800
- className: cn("mt-4 text-sm text-muted-foreground", className),
5801
- ...props
5802
- }
5803
- ));
5804
- TableCaption.displayName = "TableCaption";
5805
-
5806
- // src/ui/Tabs.tsx
5807
- import * as React10 from "react";
5808
- import * as TabsPrimitive from "@radix-ui/react-tabs";
5809
- import { jsx as jsx14 } from "react/jsx-runtime";
5810
- var Tabs = TabsPrimitive.Root;
5811
- var TabsList = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx14(
5812
- TabsPrimitive.List,
5813
- {
5814
- ref,
5815
- className: cn(
5816
- "inline-flex h-10 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground overflow-x-auto max-w-full",
5817
- className
5818
- ),
5819
- ...props
5820
- }
5821
- ));
5822
- TabsList.displayName = TabsPrimitive.List.displayName;
5823
- var TabsTrigger = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx14(
5824
- TabsPrimitive.Trigger,
5825
- {
5826
- ref,
5827
- className: cn(
5828
- "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
5829
- className
5830
- ),
5831
- ...props
5832
- }
5833
- ));
5834
- TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
5835
- var TabsContent = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx14(
5836
- TabsPrimitive.Content,
5837
- {
5838
- ref,
5839
- className: cn(
5840
- "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
5841
- className
5842
- ),
5843
- ...props
5844
- }
5845
- ));
5846
- TabsContent.displayName = TabsPrimitive.Content.displayName;
5847
-
5848
- // src/ui/Button.tsx
5849
- import * as React11 from "react";
5850
- import { Slot } from "@radix-ui/react-slot";
5851
- import { cva } from "class-variance-authority";
5852
- import { jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
5853
- var buttonVariants = cva(
5854
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
5855
- {
5856
- variants: {
5857
- variant: {
5858
- default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
5859
- destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
5860
- outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
5861
- secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
5862
- ghost: "hover:bg-accent hover:text-accent-foreground",
5863
- link: "text-primary underline-offset-4 hover:underline"
5864
- },
5865
- size: {
5866
- default: "h-10 px-4 py-2",
5867
- sm: "h-9 rounded-md px-3 text-xs",
5868
- lg: "h-11 rounded-md px-8",
5869
- icon: "h-10 w-10"
5870
- }
5871
- },
5872
- defaultVariants: {
5873
- variant: "default",
5874
- size: "default"
5875
- }
5876
- }
5877
- );
5878
- var Button = React11.forwardRef(
5879
- ({ className, variant, size, asChild = false, loading = false, disabled, children, type, ...props }, ref) => {
5880
- const Comp = asChild ? Slot : "button";
5881
- return /* @__PURE__ */ jsxs6(
5882
- Comp,
5883
- {
5884
- className: cn(buttonVariants({ variant, size, className })),
5885
- ref,
5886
- type: asChild ? void 0 : type ?? "button",
5887
- disabled: disabled || loading,
5888
- ...props,
5889
- children: [
5890
- loading && /* @__PURE__ */ jsx15("span", { className: "w-4 h-4 border-2 border-current border-t-transparent rounded-full animate-spin" }),
5891
- children
5892
- ]
5893
- }
5894
- );
5895
- }
5896
- );
5897
- Button.displayName = "Button";
5898
-
5899
- // src/ui/Input.tsx
5900
- import * as React12 from "react";
5901
- import { jsx as jsx16 } from "react/jsx-runtime";
5902
- var Input = React12.forwardRef(
5903
- ({ className, type, ...props }, ref) => {
5904
- return /* @__PURE__ */ jsx16(
5905
- "input",
5906
- {
5907
- type,
5908
- className: cn(
5909
- "flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
5910
- className
5911
- ),
5912
- ref,
5913
- ...props
5914
- }
5915
- );
5916
- }
5917
- );
5918
- Input.displayName = "Input";
5919
-
5920
- // src/ui/Textarea.tsx
5921
- import * as React13 from "react";
5922
- import { jsx as jsx17 } from "react/jsx-runtime";
5923
- var Textarea = React13.forwardRef(({ className, ...props }, ref) => {
5924
- return /* @__PURE__ */ jsx17(
5925
- "textarea",
5926
- {
5927
- className: cn(
5928
- "flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
5929
- className
5930
- ),
5931
- ref,
5932
- ...props
5933
- }
5934
- );
5935
- });
5936
- Textarea.displayName = "Textarea";
5937
-
5938
- // src/ui/Select.tsx
5939
- import * as React14 from "react";
5940
- import * as SelectPrimitive from "@radix-ui/react-select";
5941
- import { Check, ChevronDown, ChevronUp } from "lucide-react";
5942
- import { jsx as jsx18, jsxs as jsxs7 } from "react/jsx-runtime";
5943
- var Select = SelectPrimitive.Root;
5944
- var SelectGroup = SelectPrimitive.Group;
5945
- var SelectValue = SelectPrimitive.Value;
5946
- var SelectTrigger = React14.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs7(
5947
- SelectPrimitive.Trigger,
5948
- {
5949
- ref,
5950
- className: cn(
5951
- "flex h-10 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
5952
- className
5953
- ),
5954
- ...props,
5955
- children: [
5956
- children,
5957
- /* @__PURE__ */ jsx18(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx18(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
5958
- ]
5959
- }
5960
- ));
5961
- SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
5962
- var SelectScrollUpButton = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx18(
5963
- SelectPrimitive.ScrollUpButton,
5964
- {
5965
- ref,
5966
- className: cn(
5967
- "flex cursor-default items-center justify-center py-1",
5968
- className
5969
- ),
5970
- ...props,
5971
- children: /* @__PURE__ */ jsx18(ChevronUp, { className: "h-4 w-4" })
5972
- }
5973
- ));
5974
- SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
5975
- var SelectScrollDownButton = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx18(
5976
- SelectPrimitive.ScrollDownButton,
5977
- {
5978
- ref,
5979
- className: cn(
5980
- "flex cursor-default items-center justify-center py-1",
5981
- className
5982
- ),
5983
- ...props,
5984
- children: /* @__PURE__ */ jsx18(ChevronDown, { className: "h-4 w-4" })
5985
- }
5986
- ));
5987
- SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
5988
- var SelectContent = React14.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx18(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs7(
5989
- SelectPrimitive.Content,
5990
- {
5991
- ref,
5992
- className: cn(
5993
- "relative z-50 max-h-96 min-w-[8rem] max-w-[calc(100vw-2rem)] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
5994
- position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
5995
- className
5996
- ),
5997
- position,
5998
- ...props,
5999
- children: [
6000
- /* @__PURE__ */ jsx18(SelectScrollUpButton, {}),
6001
- /* @__PURE__ */ jsx18(
6002
- SelectPrimitive.Viewport,
6003
- {
6004
- className: cn(
6005
- "p-1",
6006
- position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
6007
- ),
6008
- children
6009
- }
6010
- ),
6011
- /* @__PURE__ */ jsx18(SelectScrollDownButton, {})
6012
- ]
6013
- }
6014
- ) }));
6015
- SelectContent.displayName = SelectPrimitive.Content.displayName;
6016
- var SelectLabel = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx18(
6017
- SelectPrimitive.Label,
6018
- {
6019
- ref,
6020
- className: cn("px-2 py-1.5 text-sm font-semibold", className),
6021
- ...props
6022
- }
6023
- ));
6024
- SelectLabel.displayName = SelectPrimitive.Label.displayName;
6025
- var SelectItem = React14.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs7(
6026
- SelectPrimitive.Item,
6027
- {
6028
- ref,
6029
- className: cn(
6030
- "relative flex w-full cursor-default select-none items-center rounded-sm py-2 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
6031
- className
6032
- ),
6033
- ...props,
6034
- children: [
6035
- /* @__PURE__ */ jsx18("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx18(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx18(Check, { className: "h-4 w-4" }) }) }),
6036
- /* @__PURE__ */ jsx18(SelectPrimitive.ItemText, { children })
6037
- ]
6038
- }
6039
- ));
6040
- SelectItem.displayName = SelectPrimitive.Item.displayName;
6041
- var SelectSeparator = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx18(
6042
- SelectPrimitive.Separator,
6043
- {
6044
- ref,
6045
- className: cn("-mx-1 my-1 h-px bg-muted", className),
6046
- ...props
6047
- }
6048
- ));
6049
- SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
6050
-
6051
- // src/ui/Checkbox.tsx
6052
- import * as React15 from "react";
6053
- import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
6054
- import { Check as Check2 } from "lucide-react";
6055
- import { jsx as jsx19 } from "react/jsx-runtime";
6056
- var Checkbox = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx19(
6057
- CheckboxPrimitive.Root,
6058
- {
6059
- ref,
6060
- className: cn(
6061
- "grid place-content-center peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
6062
- className
6063
- ),
6064
- ...props,
6065
- children: /* @__PURE__ */ jsx19(
6066
- CheckboxPrimitive.Indicator,
6067
- {
6068
- className: cn("grid place-content-center text-current"),
6069
- children: /* @__PURE__ */ jsx19(Check2, { className: "h-4 w-4" })
6070
- }
6071
- )
6072
- }
6073
- ));
6074
- Checkbox.displayName = CheckboxPrimitive.Root.displayName;
6075
-
6076
- // src/ui/Switch.tsx
6077
- import * as React16 from "react";
6078
- import * as SwitchPrimitives from "@radix-ui/react-switch";
6079
- import { jsx as jsx20 } from "react/jsx-runtime";
6080
- var Switch = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx20(
6081
- SwitchPrimitives.Root,
6082
- {
6083
- className: cn(
6084
- "peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
6085
- className
6086
- ),
6087
- ...props,
6088
- ref,
6089
- children: /* @__PURE__ */ jsx20(
6090
- SwitchPrimitives.Thumb,
6091
- {
6092
- className: cn(
6093
- "pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
6094
- )
6095
- }
6096
- )
6097
- }
6098
- ));
6099
- Switch.displayName = SwitchPrimitives.Root.displayName;
6100
-
6101
- // src/ui/Label.tsx
6102
- import * as React17 from "react";
6103
- import * as LabelPrimitive from "@radix-ui/react-label";
6104
- import { cva as cva2 } from "class-variance-authority";
6105
- import { jsx as jsx21 } from "react/jsx-runtime";
6106
- var labelVariants = cva2(
6107
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
6108
- );
6109
- var Label2 = React17.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx21(
6110
- LabelPrimitive.Root,
6111
- {
6112
- ref,
6113
- className: cn(labelVariants(), className),
6114
- ...props
6115
- }
6116
- ));
6117
- Label2.displayName = LabelPrimitive.Root.displayName;
6118
-
6119
- // src/ui/Badge.tsx
6120
- import { cva as cva3 } from "class-variance-authority";
6121
- import { jsx as jsx22 } from "react/jsx-runtime";
6122
- var badgeVariants = cva3(
6123
- "inline-flex items-center rounded-full border font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
6124
- {
6125
- variants: {
6126
- variant: {
6127
- default: "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
6128
- secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
6129
- destructive: "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
6130
- outline: "text-foreground",
6131
- success: "border-transparent bg-success text-success-foreground shadow hover:bg-success/80",
6132
- warning: "border-transparent bg-warning text-warning-foreground shadow hover:bg-warning/80",
6133
- info: "border-transparent bg-info text-info-foreground shadow hover:bg-info/80"
6134
- },
6135
- size: {
6136
- default: "px-2.5 py-0.5 text-xs",
6137
- sm: "px-2 py-px text-[10px]",
6138
- lg: "px-3 py-1 text-sm"
6139
- }
6140
- },
6141
- defaultVariants: {
6142
- variant: "default",
6143
- size: "default"
6144
- }
6145
- }
6146
- );
6147
- function Badge({ className, variant, size, ...props }) {
6148
- return /* @__PURE__ */ jsx22("div", { className: cn(badgeVariants({ variant, size }), className), ...props });
6149
- }
6150
-
6151
- // src/ui/Avatar.tsx
6152
- import * as React18 from "react";
6153
- import * as AvatarPrimitive from "@radix-ui/react-avatar";
6154
- import { jsx as jsx23 } from "react/jsx-runtime";
6155
- var Avatar = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx23(
6156
- AvatarPrimitive.Root,
6157
- {
6158
- ref,
6159
- className: cn(
6160
- "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
6161
- className
6162
- ),
6163
- ...props
6164
- }
6165
- ));
6166
- Avatar.displayName = AvatarPrimitive.Root.displayName;
6167
- var AvatarImage = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx23(
6168
- AvatarPrimitive.Image,
6169
- {
6170
- ref,
6171
- className: cn("aspect-square h-full w-full", className),
6172
- ...props
6173
- }
6174
- ));
6175
- AvatarImage.displayName = AvatarPrimitive.Image.displayName;
6176
- var AvatarFallback = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx23(
6177
- AvatarPrimitive.Fallback,
6178
- {
6179
- ref,
6180
- className: cn(
6181
- "flex h-full w-full items-center justify-center rounded-full bg-muted",
6182
- className
6183
- ),
6184
- ...props
6185
- }
6186
- ));
6187
- AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
6188
-
6189
- // src/ui/Progress.tsx
6190
- import * as React19 from "react";
6191
- import * as ProgressPrimitive from "@radix-ui/react-progress";
6192
- import { jsx as jsx24 } from "react/jsx-runtime";
6193
- var Progress = React19.forwardRef(({ className, value, ...props }, ref) => /* @__PURE__ */ jsx24(
6194
- ProgressPrimitive.Root,
6195
- {
6196
- ref,
6197
- className: cn(
6198
- "relative h-2 w-full overflow-hidden rounded-full bg-primary/20",
6199
- className
6200
- ),
6201
- ...props,
6202
- children: /* @__PURE__ */ jsx24(
6203
- ProgressPrimitive.Indicator,
6204
- {
6205
- className: "h-full w-full flex-1 bg-primary transition-all",
6206
- style: { transform: `translateX(-${100 - (value || 0)}%)` }
6207
- }
6208
- )
6209
- }
6210
- ));
6211
- Progress.displayName = ProgressPrimitive.Root.displayName;
6212
-
6213
- // src/ui/Skeleton.tsx
6214
- import { jsx as jsx25, jsxs as jsxs8 } from "react/jsx-runtime";
6215
- function Skeleton({
6216
- className,
6217
- ...props
6218
- }) {
6219
- return /* @__PURE__ */ jsx25(
6220
- "div",
6221
- {
6222
- className: cn("animate-pulse rounded-md bg-primary/10", className),
6223
- ...props
6224
- }
6225
- );
6226
- }
6227
- function SkeletonText({
6228
- lines = 3,
6229
- lastLineWidth = "60%",
6230
- className = ""
6231
- }) {
6232
- return /* @__PURE__ */ jsx25("div", { className: cn("space-y-2", className), children: Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ jsx25(
6233
- Skeleton,
6234
- {
6235
- className: "h-4",
6236
- style: { width: i === lines - 1 ? lastLineWidth : "100%" }
6237
- },
6238
- i
6239
- )) });
6240
- }
6241
- function SkeletonCard({ hasImage = false, className = "" }) {
6242
- return /* @__PURE__ */ jsxs8("div", { className: cn("border border-border rounded-lg overflow-hidden", className), children: [
6243
- hasImage && /* @__PURE__ */ jsx25(Skeleton, { className: "w-full h-32 rounded-none" }),
6244
- /* @__PURE__ */ jsxs8("div", { className: "p-4 space-y-3", children: [
6245
- /* @__PURE__ */ jsx25(Skeleton, { className: "h-5 w-3/4" }),
6246
- /* @__PURE__ */ jsx25(SkeletonText, { lines: 2 }),
6247
- /* @__PURE__ */ jsx25(Skeleton, { className: "h-3 w-1/3" })
6248
- ] })
6249
- ] });
6250
- }
6251
- function SkeletonList({ items = 5, className = "" }) {
6252
- return /* @__PURE__ */ jsx25("div", { className: cn("space-y-3", className), children: Array.from({ length: items }).map((_, i) => /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3 p-3 border border-border rounded-lg", children: [
6253
- /* @__PURE__ */ jsx25(Skeleton, { className: "w-10 h-10 rounded-full" }),
6254
- /* @__PURE__ */ jsxs8("div", { className: "flex-1 space-y-2", children: [
6255
- /* @__PURE__ */ jsx25(Skeleton, { className: "h-4 w-1/3" }),
6256
- /* @__PURE__ */ jsx25(Skeleton, { className: "h-3 w-1/2" })
6257
- ] }),
6258
- /* @__PURE__ */ jsx25(Skeleton, { className: "w-16 h-6" })
6259
- ] }, i)) });
6260
- }
6261
- function SkeletonTable({
6262
- rows = 5,
6263
- columns = 4,
6264
- className = ""
6265
- }) {
6266
- return /* @__PURE__ */ jsxs8("div", { className: cn("border border-border rounded-lg overflow-hidden", className), children: [
6267
- /* @__PURE__ */ jsx25("div", { className: "flex gap-4 p-4 bg-muted/50 border-b border-border", children: Array.from({ length: columns }).map((_, i) => /* @__PURE__ */ jsx25(Skeleton, { className: "h-4 flex-1" }, i)) }),
6268
- Array.from({ length: rows }).map((_, rowIndex) => /* @__PURE__ */ jsx25("div", { className: "flex gap-4 p-4 border-b border-border last:border-0", children: Array.from({ length: columns }).map((_2, colIndex) => /* @__PURE__ */ jsx25(
6269
- Skeleton,
6270
- {
6271
- className: "h-4 flex-1",
6272
- style: { width: colIndex === 0 ? "40%" : void 0 }
6273
- },
6274
- colIndex
6275
- )) }, rowIndex))
6276
- ] });
6277
- }
6278
- function SkeletonAvatar({ size = "md", className = "" }) {
6279
- const sizes = {
6280
- sm: "w-8 h-8",
6281
- md: "w-10 h-10",
6282
- lg: "w-12 h-12"
6283
- };
6284
- return /* @__PURE__ */ jsx25(Skeleton, { className: cn(sizes[size], "rounded-full", className) });
6285
- }
6286
- function LoadingSpinner({ size = "md", className = "" }) {
6287
- const sizes = {
6288
- sm: "w-4 h-4",
6289
- md: "w-6 h-6",
6290
- lg: "w-8 h-8"
6291
- };
6292
- return /* @__PURE__ */ jsx25(
6293
- "div",
6294
- {
6295
- className: cn(sizes[size], "border-2 border-muted border-t-primary rounded-full animate-spin", className)
6296
- }
6297
- );
6298
- }
6299
- function LoadingOverlay({
6300
- children,
6301
- message,
6302
- className = ""
6303
- }) {
6304
- return /* @__PURE__ */ jsxs8("div", { className: cn("flex flex-col items-center justify-center py-16", className), children: [
6305
- /* @__PURE__ */ jsx25(LoadingSpinner, { size: "lg" }),
6306
- message && /* @__PURE__ */ jsx25("p", { className: "mt-4 text-muted-foreground", children: message }),
6307
- children
6308
- ] });
6309
- }
6310
-
6311
- // src/ui/CardGrid.tsx
6312
- import { MoreHorizontal, Trash2 } from "lucide-react";
6313
- import { jsx as jsx26, jsxs as jsxs9 } from "react/jsx-runtime";
6314
- function CardGrid({ children, columns = 3, className = "", ...rest }) {
6315
- const gridCols = {
6316
- 1: "grid-cols-1",
6317
- 2: "grid-cols-1 sm:grid-cols-2",
6318
- 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
6319
- 4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
6320
- };
6321
- return /* @__PURE__ */ jsx26("div", { className: cn("grid gap-3 sm:gap-4", gridCols[columns], className), ...rest, children });
6322
- }
6323
- function GridCard({ children, onClick, className = "", hoverable = true, ...rest }) {
6324
- return /* @__PURE__ */ jsx26(
6325
- "div",
6326
- {
6327
- onClick,
6328
- className: cn(
6329
- "group relative bg-card rounded-xl border border-border overflow-hidden transition-all duration-200",
6330
- hoverable && "hover:border-border hover:shadow-card-hover hover:-translate-y-0.5",
6331
- onClick && "cursor-pointer",
6332
- className
6333
- ),
6334
- ...rest,
6335
- children
6336
- }
6337
- );
6338
- }
6339
- function GridCardImage({ src, alt = "", height = "md", className = "" }) {
6340
- const heights = {
6341
- sm: "h-24",
6342
- md: "h-36",
6343
- lg: "h-48"
6344
- };
6345
- return /* @__PURE__ */ jsx26("div", { className: cn(heights[height], "overflow-hidden bg-muted", className), children: /* @__PURE__ */ jsx26(
6346
- "img",
6347
- {
6348
- src,
6349
- alt,
6350
- referrerPolicy: "no-referrer",
6351
- className: "w-full h-full object-cover transition-transform duration-300 group-hover:scale-105"
6352
- }
6353
- ) });
6354
- }
6355
- function GridCardHeader({ children, actions, className = "" }) {
6356
- return /* @__PURE__ */ jsxs9("div", { className: cn("flex items-start justify-between gap-2 p-4 pb-2", className), children: [
6357
- /* @__PURE__ */ jsx26("div", { className: "flex-1 min-w-0", children }),
6358
- actions && /* @__PURE__ */ jsx26("div", { className: "sm:opacity-0 sm:group-hover:opacity-100 transition-opacity shrink-0", children: actions })
6359
- ] });
6360
- }
6361
- function GridCardTitle({ children, className = "" }) {
6362
- return /* @__PURE__ */ jsx26("h3", { className: cn("font-semibold text-foreground truncate", className), children });
6363
- }
6364
- function GridCardContent({ children, className = "" }) {
6365
- return /* @__PURE__ */ jsx26("div", { className: cn("px-4 pb-4", className), children });
6366
- }
6367
- function GridCardDescription({ children, lines = 2, className = "" }) {
6368
- const lineClamp = {
6369
- 1: "line-clamp-1",
6370
- 2: "line-clamp-2",
6371
- 3: "line-clamp-3",
6372
- 4: "line-clamp-4"
6373
- };
6374
- return /* @__PURE__ */ jsx26("p", { className: cn("text-sm text-muted-foreground leading-relaxed", lineClamp[lines], className), children });
6375
- }
6376
- function GridCardFooter({ children, className = "" }) {
6377
- return /* @__PURE__ */ jsx26("div", { className: cn("px-4 pb-4 pt-2 text-xs text-muted-foreground", className), children });
6378
- }
6379
- function GridCardBadge({ children, variant = "default", className = "" }) {
6380
- const variants = {
6381
- default: "bg-muted text-muted-foreground border-border",
6382
- success: "bg-success/20 text-success border-success/40",
6383
- warning: "bg-warning/20 text-warning border-warning/40",
6384
- danger: "bg-destructive/20 text-destructive border-destructive/40"
6385
- };
6386
- return /* @__PURE__ */ jsx26("span", { className: cn("inline-flex px-2 py-0.5 text-xs font-medium rounded border", variants[variant], className), children });
6387
- }
6388
- function GridCardActions({ onDelete, onMore }) {
6389
- const handleClick = (e, handler) => {
6390
- e.stopPropagation();
6391
- handler?.();
6392
- };
6393
- return /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1", children: [
6394
- onMore && /* @__PURE__ */ jsx26(
6395
- "button",
6396
- {
6397
- onClick: (e) => handleClick(e, onMore),
6398
- className: "p-2 rounded-lg bg-muted/50 hover:bg-muted text-muted-foreground hover:text-foreground transition-colors",
6399
- children: /* @__PURE__ */ jsx26(MoreHorizontal, { className: "w-4 h-4" })
6400
- }
6401
- ),
6402
- onDelete && /* @__PURE__ */ jsx26(
6403
- "button",
6404
- {
6405
- onClick: (e) => handleClick(e, onDelete),
6406
- className: "p-2 rounded-lg bg-muted/50 hover:bg-destructive/20 text-muted-foreground hover:text-destructive transition-colors",
6407
- children: /* @__PURE__ */ jsx26(Trash2, { className: "w-4 h-4" })
6408
- }
6409
- )
6410
- ] });
6411
- }
6412
- GridCard.Image = GridCardImage;
6413
- GridCard.Header = GridCardHeader;
6414
- GridCard.Title = GridCardTitle;
6415
- GridCard.Content = GridCardContent;
6416
- GridCard.Description = GridCardDescription;
6417
- GridCard.Footer = GridCardFooter;
6418
- GridCard.Badge = GridCardBadge;
6419
- GridCard.Actions = GridCardActions;
6420
-
6421
- // src/ui/Alert.tsx
6422
- import * as React20 from "react";
6423
- import { cva as cva4 } from "class-variance-authority";
6424
- import { jsx as jsx27 } from "react/jsx-runtime";
6425
- var alertVariants = cva4(
6426
- "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
6427
- {
6428
- variants: {
6429
- variant: {
6430
- default: "bg-background text-foreground",
6431
- destructive: "border-destructive/50 text-destructive [&>svg]:text-destructive",
6432
- success: "border-success/50 text-success [&>svg]:text-success",
6433
- warning: "border-warning/50 text-warning [&>svg]:text-warning",
6434
- info: "border-info/50 text-info [&>svg]:text-info"
6435
- }
6436
- },
6437
- defaultVariants: {
6438
- variant: "default"
6439
- }
6440
- }
6441
- );
6442
- var Alert = React20.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx27(
6443
- "div",
6444
- {
6445
- ref,
6446
- role: "alert",
6447
- className: cn(alertVariants({ variant }), className),
6448
- ...props
6449
- }
6450
- ));
6451
- Alert.displayName = "Alert";
6452
- var AlertTitle = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx27(
6453
- "h5",
6454
- {
6455
- ref,
6456
- className: cn("mb-1 font-medium leading-none tracking-tight", className),
6457
- ...props
6458
- }
6459
- ));
6460
- AlertTitle.displayName = "AlertTitle";
6461
- var AlertDescription = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx27(
6462
- "div",
6463
- {
6464
- ref,
6465
- className: cn("text-sm [&_p]:leading-relaxed", className),
6466
- ...props
6467
- }
6468
- ));
6469
- AlertDescription.displayName = "AlertDescription";
6470
-
6471
- // src/ui/Toast.tsx
6472
- import {
6473
- createContext as createContext4,
6474
- useContext as useContext6,
6475
- useState as useState20,
6476
- useCallback as useCallback29,
6477
- useEffect as useEffect23
6478
- } from "react";
6479
- import { jsx as jsx28, jsxs as jsxs10 } from "react/jsx-runtime";
6480
- function CheckCircleIcon({ className }) {
6481
- return /* @__PURE__ */ jsxs10("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [
6482
- /* @__PURE__ */ jsx28("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
6483
- /* @__PURE__ */ jsx28("polyline", { points: "22 4 12 14.01 9 11.01" })
6484
- ] });
6485
- }
6486
- function AlertCircleIcon({ className }) {
6487
- return /* @__PURE__ */ jsxs10("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [
6488
- /* @__PURE__ */ jsx28("circle", { cx: "12", cy: "12", r: "10" }),
6489
- /* @__PURE__ */ jsx28("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
6490
- /* @__PURE__ */ jsx28("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
6491
- ] });
6492
- }
6493
- function AlertTriangleIcon({ className }) {
6494
- return /* @__PURE__ */ jsxs10("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [
6495
- /* @__PURE__ */ jsx28("path", { d: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }),
6496
- /* @__PURE__ */ jsx28("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
6497
- /* @__PURE__ */ jsx28("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
6498
- ] });
6499
- }
6500
- function InfoIcon({ className }) {
6501
- return /* @__PURE__ */ jsxs10("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [
6502
- /* @__PURE__ */ jsx28("circle", { cx: "12", cy: "12", r: "10" }),
6503
- /* @__PURE__ */ jsx28("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
6504
- /* @__PURE__ */ jsx28("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
6505
- ] });
6506
- }
6507
- function CloseIcon({ className }) {
6508
- return /* @__PURE__ */ jsxs10("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [
6509
- /* @__PURE__ */ jsx28("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
6510
- /* @__PURE__ */ jsx28("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
6511
- ] });
6512
- }
6513
- var ToastContext = createContext4(null);
6514
- function useToast() {
6515
- const ctx = useContext6(ToastContext);
6516
- if (!ctx) throw new Error("useToast must be used within ToastProvider");
6517
- return ctx;
6518
- }
6519
- function ToastProvider({
6520
- children,
6521
- position = "bottom-right",
6522
- maxToasts = 5
6523
- }) {
6524
- const [toasts, setToasts] = useState20([]);
6525
- const dismiss = useCallback29((id) => {
6526
- setToasts((prev) => prev.filter((t) => t.id !== id));
6527
- }, []);
6528
- const dismissAll = useCallback29(() => {
6529
- setToasts([]);
6530
- }, []);
6531
- const addToast = useCallback29(
6532
- (options) => {
6533
- const id = Math.random().toString(36).slice(2);
6534
- const duration = options.duration ?? 5e3;
6535
- setToasts((prev) => {
6536
- const next = [...prev, { ...options, id }];
6537
- return next.slice(-maxToasts);
6538
- });
6539
- if (duration > 0) {
6540
- setTimeout(() => dismiss(id), duration);
6541
- }
6542
- },
6543
- [dismiss, maxToasts]
6544
- );
6545
- const toast = useCallback29(
6546
- (options) => addToast(options),
6547
- [addToast]
6548
- );
6549
- const success = useCallback29(
6550
- (title, description) => addToast({ type: "success", title, description }),
6551
- [addToast]
6552
- );
6553
- const error = useCallback29(
6554
- (title, description) => addToast({ type: "error", title, description }),
6555
- [addToast]
6556
- );
6557
- const warning = useCallback29(
6558
- (title, description) => addToast({ type: "warning", title, description }),
6559
- [addToast]
6560
- );
6561
- const info = useCallback29(
6562
- (title, description) => addToast({ type: "info", title, description }),
6563
- [addToast]
6564
- );
6565
- const positionClasses = {
6566
- "top-right": "top-4 right-4",
6567
- "top-left": "top-4 left-4",
6568
- "bottom-right": "bottom-4 right-4",
6569
- "bottom-left": "bottom-4 left-4",
6570
- "top-center": "top-4 left-1/2 -translate-x-1/2",
6571
- "bottom-center": "bottom-4 left-1/2 -translate-x-1/2"
6572
- };
6573
- return /* @__PURE__ */ jsxs10(
6574
- ToastContext.Provider,
6575
- {
6576
- value: { toasts, toast, success, error, warning, info, dismiss, dismissAll },
6577
- children: [
6578
- children,
6579
- /* @__PURE__ */ jsx28(
6580
- "div",
6581
- {
6582
- className: `fixed z-[100] flex flex-col gap-2 ${positionClasses[position]}`,
6583
- children: toasts.map((t) => /* @__PURE__ */ jsx28(ToastItem, { toast: t, onDismiss: () => dismiss(t.id) }, t.id))
6584
- }
6585
- )
6586
- ]
6587
- }
6588
- );
6589
- }
6590
- var TOAST_CONFIG = {
6591
- success: { Icon: CheckCircleIcon, accent: "bg-success", icon: "text-success" },
6592
- error: { Icon: AlertCircleIcon, accent: "bg-destructive", icon: "text-destructive" },
6593
- warning: { Icon: AlertTriangleIcon, accent: "bg-warning", icon: "text-warning" },
6594
- info: { Icon: InfoIcon, accent: "bg-info", icon: "text-info" }
6595
- };
6596
- function ToastItem({ toast, onDismiss }) {
6597
- const { Icon: Icon2, accent, icon } = TOAST_CONFIG[toast.type];
6598
- const [exiting, setExiting] = useState20(false);
6599
- useEffect23(() => {
6600
- if (exiting) {
6601
- const timer = setTimeout(onDismiss, 150);
6602
- return () => clearTimeout(timer);
6603
- }
6604
- }, [exiting, onDismiss]);
6605
- return /* @__PURE__ */ jsxs10(
6606
- "div",
6607
- {
6608
- className: `
6609
- relative flex items-start gap-2.5 min-w-[260px] max-w-[360px]
6610
- overflow-hidden rounded-lg border border-border bg-popover
6611
- text-popover-foreground pl-3.5 pr-2 py-2.5 shadow-lg
6612
- ${exiting ? "animate-out fade-out-0 slide-out-to-right-2 duration-150" : "animate-in fade-in-0 slide-in-from-right-2 duration-200"}
6613
- `,
6614
- role: "alert",
6615
- children: [
6616
- /* @__PURE__ */ jsx28("span", { className: `absolute inset-y-0 left-0 w-[3px] ${accent}`, "aria-hidden": true }),
6617
- /* @__PURE__ */ jsx28(Icon2, { className: `mt-0.5 h-4 w-4 shrink-0 ${icon}` }),
6618
- /* @__PURE__ */ jsxs10("div", { className: "flex-1 min-w-0", children: [
6619
- /* @__PURE__ */ jsx28("p", { className: "text-[13px] font-medium leading-tight", children: toast.title }),
6620
- toast.description && /* @__PURE__ */ jsx28("p", { className: "mt-0.5 text-xs leading-snug text-muted-foreground", children: toast.description })
6621
- ] }),
6622
- /* @__PURE__ */ jsx28(
6623
- "button",
6624
- {
6625
- onClick: () => setExiting(true),
6626
- className: "-mr-0.5 shrink-0 rounded p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
6627
- "aria-label": "Dismiss",
6628
- children: /* @__PURE__ */ jsx28(CloseIcon, { className: "h-3.5 w-3.5" })
6629
- }
6630
- )
6631
- ]
6632
- }
6633
- );
6634
- }
6635
-
6636
- // src/ui/ErrorBoundary.tsx
6637
- import { AlertTriangle, RefreshCw } from "lucide-react";
6638
- import { jsx as jsx29, jsxs as jsxs11 } from "react/jsx-runtime";
6639
- var REACT_ERROR_TABLE = {
6640
- 300: {
6641
- title: "A component changed how many hooks it runs",
6642
- explanation: "This component called fewer hooks than it did on its previous render.",
6643
- hint: "Almost always an early return placed above a hook. Move every hook (useState, useEffect, useQuery, \u2026) above any conditional return so the same hooks run in the same order on every render."
6644
- },
6645
- 310: {
6646
- title: "A component changed how many hooks it runs",
6647
- explanation: "This component called more hooks than it did on its previous render.",
6648
- hint: "Almost always an early return placed above a hook. Move every hook (useState, useEffect, useQuery, \u2026) above any conditional return so the same hooks run in the same order on every render."
6649
- },
6650
- 301: {
6651
- title: "Too many re-renders",
6652
- explanation: "React hit its render limit because the component updated state while rendering, which triggers an infinite render loop.",
6653
- hint: "Don\u2019t call setState (or a mutation) directly in the render body. Move it into an event handler or an effect with the right dependencies."
6654
- },
6655
- 321: {
6656
- title: "A hook was called in an invalid place",
6657
- explanation: "Hooks can only be called at the top level of a function component or another hook.",
6658
- hint: "Move the hook out of any condition, loop, callback, or plain (non-component) function. This can also mean two copies of React are installed."
6659
- }
6660
- };
6661
- function extractReactErrorCode(message) {
6662
- const patterns = [/react\.dev\/errors\/(\d+)/, /invariant=(\d+)/, /Minified React error #(\d+)/];
6663
- for (const re of patterns) {
6664
- const match = message.match(re);
6665
- if (match) return Number(match[1]);
6666
- }
6667
- return null;
6668
- }
6669
- function errorMessage(error) {
6670
- if (typeof error === "string") return error;
6671
- if (error instanceof Error) return error.message;
6672
- return null;
6673
- }
6674
- function decodeReactError(error) {
6675
- const message = errorMessage(error);
6676
- if (!message) return null;
6677
- const code = extractReactErrorCode(message);
6678
- if (code == null) return null;
6679
- const known = REACT_ERROR_TABLE[code];
6680
- return {
6681
- code,
6682
- docsUrl: `https://react.dev/errors/${code}`,
6683
- title: known?.title ?? `React error #${code}`,
6684
- explanation: known?.explanation ?? "React stopped rendering because of an error.",
6685
- hint: known?.hint ?? "Run the app in development (npm run dev) to see the full, unminified message and the component that failed."
6686
- };
6687
- }
6688
- function ErrorScreen({ error, onReset }) {
6689
- const decoded = decodeReactError(error);
6690
- const rawMessage = error instanceof Error ? error.message : typeof error === "string" ? error : "";
6691
- const stack = error instanceof Error ? error.stack : void 0;
6692
- const reset = onReset ?? (() => window.location.reload());
6693
- return /* @__PURE__ */ jsx29(
6694
- "div",
6695
- {
6696
- "data-testid": "ds-error-boundary",
6697
- className: "flex h-full min-h-[60vh] flex-col items-center justify-center bg-background px-4 py-10 text-foreground",
6698
- children: /* @__PURE__ */ jsxs11("div", { className: "w-full max-w-lg text-center", children: [
6699
- /* @__PURE__ */ jsx29("div", { className: "mb-4 flex justify-center", children: /* @__PURE__ */ jsx29("span", { className: "inline-flex h-12 w-12 items-center justify-center rounded-full bg-destructive/10 text-destructive", children: /* @__PURE__ */ jsx29(AlertTriangle, { className: "h-6 w-6", "aria-hidden": true }) }) }),
6700
- /* @__PURE__ */ jsx29("h1", { className: "text-lg font-semibold tracking-tight", children: decoded?.title ?? "Something went wrong" }),
6701
- decoded?.explanation && /* @__PURE__ */ jsx29("p", { className: "mt-1.5 text-sm text-muted-foreground", children: decoded.explanation }),
6702
- decoded?.hint && /* @__PURE__ */ jsxs11(Alert, { variant: "warning", className: "mt-4 text-left", children: [
6703
- /* @__PURE__ */ jsx29(AlertTitle, { children: "How to fix" }),
6704
- /* @__PURE__ */ jsx29(AlertDescription, { children: decoded.hint })
6705
- ] }),
6706
- rawMessage && /* @__PURE__ */ jsx29("pre", { className: "mt-4 overflow-x-auto rounded-lg border bg-muted/40 px-3 py-2 text-left text-xs text-muted-foreground", children: rawMessage }),
6707
- stack && /* @__PURE__ */ jsxs11("details", { className: "mt-2 text-left", children: [
6708
- /* @__PURE__ */ jsx29("summary", { className: "cursor-pointer text-xs text-muted-foreground", children: "Show stack trace" }),
6709
- /* @__PURE__ */ jsx29("pre", { className: "mt-1 max-h-60 overflow-auto rounded-lg border bg-muted/40 px-3 py-2 text-xs text-muted-foreground", children: stack })
6710
- ] }),
6711
- /* @__PURE__ */ jsxs11("div", { className: "mt-6 flex items-center justify-center gap-3", children: [
6712
- /* @__PURE__ */ jsxs11(Button, { onClick: reset, children: [
6713
- /* @__PURE__ */ jsx29(RefreshCw, { className: "h-4 w-4", "aria-hidden": true }),
6714
- "Reload"
6715
- ] }),
6716
- decoded && /* @__PURE__ */ jsxs11(
6717
- "a",
6718
- {
6719
- href: decoded.docsUrl,
6720
- target: "_blank",
6721
- rel: "noreferrer",
6722
- className: "text-sm text-muted-foreground underline-offset-4 hover:underline",
6723
- children: [
6724
- "React error #",
6725
- decoded.code,
6726
- " reference"
6727
- ]
6728
- }
6729
- )
6730
- ] })
6731
- ] })
6732
- }
6733
- );
6734
- }
6735
-
6736
- // src/ui/EmptyState.tsx
6737
- import { FileText, Search, Inbox, Plus, FolderOpen, Users, AlertCircle } from "lucide-react";
6738
- import { jsx as jsx30, jsxs as jsxs12 } from "react/jsx-runtime";
6739
- function EmptyState({
6740
- icon,
6741
- title,
6742
- description,
6743
- action,
6744
- secondaryAction,
6745
- className = "",
6746
- ...rest
6747
- }) {
6748
- return /* @__PURE__ */ jsxs12("div", { className: cn("flex flex-col items-center justify-center py-16 px-4 text-center", className), ...rest, children: [
6749
- icon && /* @__PURE__ */ jsx30("div", { className: "w-16 h-16 rounded-2xl bg-muted/50 border border-border flex items-center justify-center mb-5", children: /* @__PURE__ */ jsx30("span", { className: "text-muted-foreground", children: icon }) }),
6750
- /* @__PURE__ */ jsx30("h3", { className: "text-lg font-semibold text-foreground mb-2", children: title }),
6751
- description && /* @__PURE__ */ jsx30("p", { className: "text-muted-foreground text-sm max-w-sm mb-6", children: description }),
6752
- (action || secondaryAction) && /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-3", children: [
6753
- action && /* @__PURE__ */ jsxs12(
6754
- "button",
6755
- {
6756
- onClick: action.onClick,
6757
- className: "inline-flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-lg font-medium text-sm hover:bg-primary/90 shadow-lg shadow-primary/25 transition-all",
6758
- children: [
6759
- /* @__PURE__ */ jsx30(Plus, { className: "w-4 h-4" }),
6760
- action.label
6761
- ]
6762
- }
6763
- ),
6764
- secondaryAction && /* @__PURE__ */ jsx30(
6765
- "button",
6766
- {
6767
- onClick: secondaryAction.onClick,
6768
- className: "px-4 py-2 text-sm text-muted-foreground hover:text-foreground transition-colors",
6769
- children: secondaryAction.label
6770
- }
6771
- )
6772
- ] })
6773
- ] });
6774
- }
6775
- function EmptyItems({ action, className }) {
6776
- return /* @__PURE__ */ jsx30(
6777
- EmptyState,
6778
- {
6779
- icon: /* @__PURE__ */ jsx30(Inbox, { className: "w-8 h-8" }),
6780
- title: "No items yet",
6781
- description: "Get started by creating your first item.",
6782
- action: action ? { label: action.label, onClick: action.onClick } : void 0,
6783
- className
6784
- }
6785
- );
6786
- }
6787
- function EmptySearch({ query, onClear, className }) {
6788
- return /* @__PURE__ */ jsx30(
6789
- EmptyState,
6790
- {
6791
- icon: /* @__PURE__ */ jsx30(Search, { className: "w-8 h-8" }),
6792
- title: "No results found",
6793
- description: query ? `No results for "${query}". Try a different search term.` : "Try adjusting your search or filters.",
6794
- secondaryAction: onClear ? { label: "Clear search", onClick: onClear } : void 0,
6795
- className
6796
- }
6797
- );
6798
- }
6799
- function EmptyDocuments({ action, className }) {
6800
- return /* @__PURE__ */ jsx30(
6801
- EmptyState,
6802
- {
6803
- icon: /* @__PURE__ */ jsx30(FileText, { className: "w-8 h-8" }),
6804
- title: "No documents",
6805
- description: "Create a document to start writing.",
6806
- action: action ? { label: action.label, onClick: action.onClick } : void 0,
6807
- className
6808
- }
6809
- );
6810
- }
6811
- function EmptyProjects({ action, className }) {
6812
- return /* @__PURE__ */ jsx30(
6813
- EmptyState,
6814
- {
6815
- icon: /* @__PURE__ */ jsx30(FolderOpen, { className: "w-8 h-8" }),
6816
- title: "No projects",
6817
- description: "Create a project to organize your work.",
6818
- action: action ? { label: action.label, onClick: action.onClick } : void 0,
6819
- className
6820
- }
6821
- );
6822
- }
6823
- function EmptyTeam({ action, className }) {
6824
- return /* @__PURE__ */ jsx30(
6825
- EmptyState,
6826
- {
6827
- icon: /* @__PURE__ */ jsx30(Users, { className: "w-8 h-8" }),
6828
- title: "No team members",
6829
- description: "Invite people to collaborate with you.",
6830
- action: action ? { label: action.label, onClick: action.onClick } : void 0,
6831
- className
6832
- }
6833
- );
6834
- }
6835
- function EmptyError({ error, onRetry, className }) {
6836
- return /* @__PURE__ */ jsx30(
6837
- EmptyState,
6838
- {
6839
- icon: /* @__PURE__ */ jsx30(AlertCircle, { className: "w-8 h-8 text-destructive" }),
6840
- title: "Something went wrong",
6841
- description: error || "An error occurred. Please try again.",
6842
- action: onRetry ? { label: "Try again", onClick: onRetry } : void 0,
6843
- className
6844
- }
6845
- );
6846
- }
6847
-
6848
- // src/ui/Dialog.tsx
6849
- import * as React22 from "react";
6850
- import * as DialogPrimitive from "@radix-ui/react-dialog";
6851
- import { X } from "lucide-react";
6852
- import { jsx as jsx31, jsxs as jsxs13 } from "react/jsx-runtime";
6853
- var Dialog = DialogPrimitive.Root;
6854
- var DialogTrigger = DialogPrimitive.Trigger;
6855
- var DialogPortal = DialogPrimitive.Portal;
6856
- var DialogClose = DialogPrimitive.Close;
6857
- var DialogOverlay = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx31(
6858
- DialogPrimitive.Overlay,
6859
- {
6860
- ref,
6861
- className: cn(
6862
- "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
6863
- className
6864
- ),
6865
- ...props
6866
- }
6867
- ));
6868
- DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
6869
- var DialogContent = React22.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs13(DialogPortal, { children: [
6870
- /* @__PURE__ */ jsx31(DialogOverlay, {}),
6871
- /* @__PURE__ */ jsxs13(
6872
- DialogPrimitive.Content,
6873
- {
6874
- ref,
6875
- className: cn(
6876
- "fixed left-[50%] top-[50%] z-50 grid w-full max-w-[calc(100vw-2rem)] sm:max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-border bg-background/95 backdrop-blur-2xl p-4 sm:p-6 shadow-card-hover duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 sm:rounded-2xl",
6877
- className
6878
- ),
6879
- ...props,
6880
- children: [
6881
- children,
6882
- /* @__PURE__ */ jsxs13(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm p-1 opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [
6883
- /* @__PURE__ */ jsx31(X, { className: "h-4 w-4" }),
6884
- /* @__PURE__ */ jsx31("span", { className: "sr-only", children: "Close" })
6885
- ] })
6886
- ]
6887
- }
6888
- )
6889
- ] }));
6890
- DialogContent.displayName = DialogPrimitive.Content.displayName;
6891
- var DialogHeader = ({
6892
- className,
6893
- ...props
6894
- }) => /* @__PURE__ */ jsx31(
6895
- "div",
6896
- {
6897
- className: cn(
6898
- "flex flex-col space-y-1.5 text-center sm:text-left",
6899
- className
6900
- ),
6901
- ...props
6902
- }
6903
- );
6904
- DialogHeader.displayName = "DialogHeader";
6905
- var DialogFooter = ({
6906
- className,
6907
- ...props
6908
- }) => /* @__PURE__ */ jsx31(
6909
- "div",
6910
- {
6911
- className: cn(
6912
- "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
6913
- className
6914
- ),
6915
- ...props
6916
- }
6917
- );
6918
- DialogFooter.displayName = "DialogFooter";
6919
- var DialogTitle = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx31(
6920
- DialogPrimitive.Title,
6921
- {
6922
- ref,
6923
- className: cn(
6924
- "text-lg font-semibold leading-none tracking-tight",
6925
- className
6926
- ),
6927
- ...props
6928
- }
6929
- ));
6930
- DialogTitle.displayName = DialogPrimitive.Title.displayName;
6931
- var DialogDescription = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx31(
6932
- DialogPrimitive.Description,
6933
- {
6934
- ref,
6935
- className: cn("text-sm text-muted-foreground", className),
6936
- ...props
6937
- }
6938
- ));
6939
- DialogDescription.displayName = DialogPrimitive.Description.displayName;
6940
-
6941
- // src/ui/DropdownMenu.tsx
6942
- import * as React23 from "react";
6943
- import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
6944
- import { Check as Check3, ChevronRight, Circle } from "lucide-react";
6945
- import { jsx as jsx32, jsxs as jsxs14 } from "react/jsx-runtime";
6946
- var DropdownMenu = DropdownMenuPrimitive.Root;
6947
- var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
6948
- var DropdownMenuGroup = DropdownMenuPrimitive.Group;
6949
- var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
6950
- var DropdownMenuSub = DropdownMenuPrimitive.Sub;
6951
- var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
6952
- var DropdownMenuSubTrigger = React23.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs14(
6953
- DropdownMenuPrimitive.SubTrigger,
6954
- {
6955
- ref,
6956
- className: cn(
6957
- "flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
6958
- inset && "pl-8",
6959
- className
6960
- ),
6961
- ...props,
6962
- children: [
6963
- children,
6964
- /* @__PURE__ */ jsx32(ChevronRight, { className: "ml-auto" })
6965
- ]
6966
- }
6967
- ));
6968
- DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
6969
- var DropdownMenuSubContent = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx32(
6970
- DropdownMenuPrimitive.SubContent,
6971
- {
6972
- ref,
6973
- className: cn(
6974
- "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
6975
- className
6976
- ),
6977
- ...props
6978
- }
6979
- ));
6980
- DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
6981
- var DropdownMenuContent = React23.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx32(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx32(
6982
- DropdownMenuPrimitive.Content,
6983
- {
6984
- ref,
6985
- sideOffset,
6986
- className: cn(
6987
- "z-50 min-w-[8rem] max-w-[calc(100vw-1rem)] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
6988
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
6989
- className
6990
- ),
6991
- ...props
6992
- }
6993
- ) }));
6994
- DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
6995
- var DropdownMenuItem = React23.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx32(
6996
- DropdownMenuPrimitive.Item,
6997
- {
6998
- ref,
6999
- className: cn(
7000
- "relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
7001
- inset && "pl-8",
7002
- className
7003
- ),
7004
- ...props
7005
- }
7006
- ));
7007
- DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
7008
- var DropdownMenuCheckboxItem = React23.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs14(
7009
- DropdownMenuPrimitive.CheckboxItem,
7010
- {
7011
- ref,
7012
- className: cn(
7013
- "relative flex cursor-default select-none items-center rounded-sm py-2 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
7014
- className
7015
- ),
7016
- checked,
7017
- ...props,
7018
- children: [
7019
- /* @__PURE__ */ jsx32("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx32(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx32(Check3, { className: "h-4 w-4" }) }) }),
7020
- children
7021
- ]
7022
- }
7023
- ));
7024
- DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
7025
- var DropdownMenuRadioItem = React23.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs14(
7026
- DropdownMenuPrimitive.RadioItem,
7027
- {
7028
- ref,
7029
- className: cn(
7030
- "relative flex cursor-default select-none items-center rounded-sm py-2 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
7031
- className
7032
- ),
7033
- ...props,
7034
- children: [
7035
- /* @__PURE__ */ jsx32("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx32(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx32(Circle, { className: "h-2 w-2 fill-current" }) }) }),
7036
- children
7037
- ]
7038
- }
7039
- ));
7040
- DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
7041
- var DropdownMenuLabel = React23.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx32(
7042
- DropdownMenuPrimitive.Label,
7043
- {
7044
- ref,
7045
- className: cn(
7046
- "px-2 py-1.5 text-sm font-semibold",
7047
- inset && "pl-8",
7048
- className
7049
- ),
7050
- ...props
7051
- }
7052
- ));
7053
- DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
7054
- var DropdownMenuSeparator = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx32(
7055
- DropdownMenuPrimitive.Separator,
7056
- {
7057
- ref,
7058
- className: cn("-mx-1 my-1 h-px bg-muted", className),
7059
- ...props
7060
- }
7061
- ));
7062
- DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
7063
- var DropdownMenuShortcut = ({
7064
- className,
7065
- ...props
7066
- }) => {
7067
- return /* @__PURE__ */ jsx32(
7068
- "span",
7069
- {
7070
- className: cn("ml-auto text-xs tracking-widest opacity-60", className),
7071
- ...props
7072
- }
7073
- );
7074
- };
7075
- DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
7076
-
7077
- // src/ui/Tooltip.tsx
7078
- import * as React24 from "react";
7079
- import * as TooltipPrimitive from "@radix-ui/react-tooltip";
7080
- import { jsx as jsx33 } from "react/jsx-runtime";
7081
- var TooltipProvider = TooltipPrimitive.Provider;
7082
- var Tooltip = TooltipPrimitive.Root;
7083
- var TooltipTrigger = TooltipPrimitive.Trigger;
7084
- var TooltipContent = React24.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx33(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx33(
7085
- TooltipPrimitive.Content,
7086
- {
7087
- ref,
7088
- sideOffset,
7089
- className: cn(
7090
- "z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
7091
- className
7092
- ),
7093
- ...props
7094
- }
7095
- ) }));
7096
- TooltipContent.displayName = TooltipPrimitive.Content.displayName;
7097
-
7098
- // src/ui/Modal.tsx
7099
- import { jsx as jsx34, jsxs as jsxs15 } from "react/jsx-runtime";
7100
- function Modal({
7101
- open,
7102
- onClose,
7103
- children,
7104
- size = "md",
7105
- className
7106
- }) {
7107
- const sizes = {
7108
- sm: "max-w-[calc(100vw-2rem)] sm:max-w-sm",
7109
- md: "max-w-[calc(100vw-2rem)] sm:max-w-lg",
7110
- lg: "max-w-[calc(100vw-2rem)] sm:max-w-2xl",
7111
- xl: "max-w-[calc(100vw-2rem)] sm:max-w-4xl"
7112
- };
7113
- return /* @__PURE__ */ jsx34(Dialog, { open, onOpenChange: (v) => {
7114
- if (!v) onClose();
7115
- }, children: /* @__PURE__ */ jsx34(DialogContent, { "aria-describedby": void 0, className: cn(sizes[size], "flex flex-col max-h-[85vh]", className), children }) });
7116
- }
7117
- function ModalHeader({ children, className = "" }) {
7118
- return /* @__PURE__ */ jsx34(DialogHeader, { className, children });
7119
- }
7120
- function ModalTitle({ children, className = "" }) {
7121
- return /* @__PURE__ */ jsx34(DialogTitle, { className, children });
7122
- }
7123
- function ModalDescription({ children, className = "" }) {
7124
- return /* @__PURE__ */ jsx34(DialogDescription, { className, children });
7125
- }
7126
- function ModalBody({ children, className = "" }) {
7127
- return /* @__PURE__ */ jsx34("div", { className: cn("flex-1 overflow-y-auto py-4", className), children });
7128
- }
7129
- function ModalFooter({ children, className = "" }) {
7130
- return /* @__PURE__ */ jsx34(DialogFooter, { className, children });
7131
- }
7132
- function ConfirmModal({
7133
- open,
7134
- onClose,
7135
- onConfirm,
7136
- title,
7137
- description,
7138
- confirmText = "Confirm",
7139
- cancelText = "Cancel",
7140
- variant = "destructive",
7141
- loading = false
7142
- }) {
7143
- return /* @__PURE__ */ jsxs15(Modal, { open, onClose, size: "sm", children: [
7144
- /* @__PURE__ */ jsxs15(Modal.Header, { children: [
7145
- /* @__PURE__ */ jsx34(Modal.Title, { children: title }),
7146
- description && /* @__PURE__ */ jsx34(Modal.Description, { children: description })
7147
- ] }),
7148
- /* @__PURE__ */ jsxs15(Modal.Footer, { children: [
7149
- /* @__PURE__ */ jsx34(Button, { variant: "ghost", onClick: onClose, disabled: loading, children: cancelText }),
7150
- /* @__PURE__ */ jsx34(Button, { variant, onClick: onConfirm, loading, children: confirmText })
7151
- ] })
7152
- ] });
7153
- }
7154
- Modal.Header = ModalHeader;
7155
- Modal.Title = ModalTitle;
7156
- Modal.Description = ModalDescription;
7157
- Modal.Body = ModalBody;
7158
- Modal.Footer = ModalFooter;
7159
-
7160
- // src/ui/SearchInput.tsx
7161
- import * as React25 from "react";
7162
- import { Search as Search2, X as X2 } from "lucide-react";
7163
- import { jsx as jsx35, jsxs as jsxs16 } from "react/jsx-runtime";
7164
- var SearchInput = React25.forwardRef(
7165
- ({ className, onClear, value, ...props }, ref) => {
7166
- return /* @__PURE__ */ jsxs16("div", { className: "relative", children: [
7167
- /* @__PURE__ */ jsx35(Search2, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }),
7168
- /* @__PURE__ */ jsx35(
7169
- Input,
7170
- {
7171
- ref,
7172
- type: "search",
7173
- className: cn("pl-9 pr-9", className),
7174
- value,
7175
- ...props
7176
- }
7177
- ),
7178
- value && onClear && /* @__PURE__ */ jsx35(
7179
- "button",
7180
- {
7181
- type: "button",
7182
- onClick: onClear,
7183
- className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground hover:text-foreground transition-colors",
7184
- children: /* @__PURE__ */ jsx35(X2, { className: "h-4 w-4" })
7185
- }
7186
- )
7187
- ] });
7188
- }
7189
- );
7190
- SearchInput.displayName = "SearchInput";
7191
5871
  export {
7192
5872
  ASYNC_RESOURCE_DEFAULTS,
7193
- Alert,
7194
- AlertDescription,
7195
- AlertTitle,
7196
5873
  AuthGate,
7197
5874
  AuthOverlay,
7198
- Avatar,
7199
- AvatarFallback,
7200
- AvatarImage,
7201
5875
  Awareness,
7202
- Badge,
7203
- Button,
7204
- Card,
7205
- CardContent,
7206
- CardDescription,
7207
- CardFooter,
7208
- CardGrid,
7209
- CardHeader,
7210
- CardTitle,
7211
- Checkbox,
7212
- ConfirmModal,
7213
5876
  DEEPSPACE_THEME_PROPERTIES,
7214
5877
  DEFAULT_USER_COLORS,
7215
5878
  DeepSpaceAuthProvider,
7216
5879
  DeepSpaceThemeProvider,
7217
- Dialog,
7218
- DialogClose,
7219
- DialogContent,
7220
- DialogDescription,
7221
- DialogFooter,
7222
- DialogHeader,
7223
- DialogOverlay,
7224
- DialogPortal,
7225
- DialogTitle,
7226
- DialogTrigger,
7227
- DropdownMenu,
7228
- DropdownMenuCheckboxItem,
7229
- DropdownMenuContent,
7230
- DropdownMenuGroup,
7231
- DropdownMenuItem,
7232
- DropdownMenuLabel,
7233
- DropdownMenuPortal,
7234
- DropdownMenuRadioGroup,
7235
- DropdownMenuRadioItem,
7236
- DropdownMenuSeparator,
7237
- DropdownMenuShortcut,
7238
- DropdownMenuSub,
7239
- DropdownMenuSubContent,
7240
- DropdownMenuSubTrigger,
7241
- DropdownMenuTrigger,
7242
5880
  ENV,
7243
- EmptyDocuments,
7244
- EmptyError,
7245
- EmptyItems,
7246
- EmptyProjects,
7247
- EmptySearch,
7248
- EmptyState,
7249
- EmptyTeam,
7250
- ErrorScreen,
7251
- GridCard,
7252
5881
  GuestBanner,
7253
- Input,
7254
- Label2 as Label,
7255
- LoadingOverlay,
7256
- LoadingSpinner,
7257
5882
  MSG,
7258
5883
  MSG_AWARENESS,
7259
5884
  MSG_SYNC,
@@ -7262,11 +5887,9 @@ export {
7262
5887
  MSG_SYNC_UPDATE,
7263
5888
  MSG_YJS_AWARENESS,
7264
5889
  MSG_YJS_SYNC,
7265
- Modal,
7266
5890
  PlatformContext,
7267
5891
  PlatformProvider,
7268
5892
  PricingTable,
7269
- Progress,
7270
5893
  ROLES,
7271
5894
  ROLE_ADMIN,
7272
5895
  ROLE_ANONYMOUS,
@@ -7275,58 +5898,19 @@ export {
7275
5898
  RecordProvider,
7276
5899
  RecordScope,
7277
5900
  ScopeRegistryProvider,
7278
- SearchInput,
7279
- Select,
7280
- SelectContent,
7281
- SelectGroup,
7282
- SelectItem,
7283
- SelectLabel,
7284
- SelectSeparator,
7285
- SelectTrigger,
7286
- SelectValue,
7287
- Separator,
7288
5901
  SignedIn,
7289
5902
  SignedOut,
7290
- Skeleton,
7291
- SkeletonAvatar,
7292
- SkeletonCard,
7293
- SkeletonList,
7294
- SkeletonTable,
7295
- SkeletonText,
7296
- Switch,
7297
- Table,
7298
- TableBody,
7299
- TableCaption,
7300
- TableCell,
7301
- TableFooter,
7302
- TableHead,
7303
- TableHeader,
7304
- TableRow,
7305
- Tabs,
7306
- TabsContent,
7307
- TabsList,
7308
- TabsTrigger,
7309
- Textarea,
7310
- ToastProvider,
7311
- Tooltip,
7312
- TooltipContent,
7313
- TooltipProvider,
7314
- TooltipTrigger,
7315
5903
  applyDeepSpaceTheme,
7316
5904
  applyUIThemeTokens,
7317
5905
  authClient,
7318
- badgeVariants,
7319
- buttonVariants,
7320
5906
  canAutoLoadPagedResource,
7321
5907
  clampPagedResourceItems,
7322
5908
  clearAuthToken,
7323
5909
  clearDeepSpaceTheme,
7324
5910
  clientBuild,
7325
- cn,
7326
5911
  createDecoder,
7327
5912
  createEncoder,
7328
5913
  decodeAiStreamChunk,
7329
- decodeReactError,
7330
5914
  deriveLoadState,
7331
5915
  detectEnvironment,
7332
5916
  dispatch,
@@ -7406,10 +5990,10 @@ export {
7406
5990
  useRecordContext,
7407
5991
  useSession,
7408
5992
  useSubscription,
7409
- useToast,
7410
5993
  useUser,
7411
5994
  useUserLookup,
7412
5995
  useUsers,
5996
+ useVoiceAgent,
7413
5997
  useYjsField,
7414
5998
  useYjsRoom,
7415
5999
  useYjsText,