keynesol-shared 1.0.0

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.
Files changed (154) hide show
  1. package/README.md +118 -0
  2. package/dist/components/Common/ErrorBoundary.d.ts +23 -0
  3. package/dist/components/Common/ErrorBoundary.d.ts.map +1 -0
  4. package/dist/components/Common/ErrorBoundary.js +93 -0
  5. package/dist/components/Common/ErrorBoundary.jsx +103 -0
  6. package/dist/components/Common/ErrorMessage.d.ts +8 -0
  7. package/dist/components/Common/ErrorMessage.d.ts.map +1 -0
  8. package/dist/components/Common/ErrorMessage.js +36 -0
  9. package/dist/components/Common/ErrorMessage.jsx +40 -0
  10. package/dist/components/Common/Loading.d.ts +8 -0
  11. package/dist/components/Common/Loading.d.ts.map +1 -0
  12. package/dist/components/Common/Loading.js +41 -0
  13. package/dist/components/Common/Loading.jsx +44 -0
  14. package/dist/components/Common/LoadingIndicator.d.ts +17 -0
  15. package/dist/components/Common/LoadingIndicator.d.ts.map +1 -0
  16. package/dist/components/Common/LoadingIndicator.js +95 -0
  17. package/dist/components/Common/LoadingIndicator.jsx +108 -0
  18. package/dist/components/Common/ProgramStatus.d.ts +3 -0
  19. package/dist/components/Common/ProgramStatus.d.ts.map +1 -0
  20. package/dist/components/Common/ProgramStatus.js +26 -0
  21. package/dist/components/Common/ProgramStatus.jsx +27 -0
  22. package/dist/components/Common/Skeleton.d.ts +39 -0
  23. package/dist/components/Common/Skeleton.d.ts.map +1 -0
  24. package/dist/components/Common/Skeleton.js +53 -0
  25. package/dist/components/Common/Skeleton.jsx +67 -0
  26. package/dist/components/Common/SkeletonScreen.d.ts +18 -0
  27. package/dist/components/Common/SkeletonScreen.d.ts.map +1 -0
  28. package/dist/components/Common/SkeletonScreen.js +98 -0
  29. package/dist/components/Common/SkeletonScreen.jsx +108 -0
  30. package/dist/components/Common/index.d.ts +11 -0
  31. package/dist/components/Common/index.d.ts.map +1 -0
  32. package/dist/components/Common/index.js +10 -0
  33. package/dist/components/Wallet/TransactionStatus.d.ts +11 -0
  34. package/dist/components/Wallet/TransactionStatus.d.ts.map +1 -0
  35. package/dist/components/Wallet/TransactionStatus.js +97 -0
  36. package/dist/components/Wallet/TransactionStatus.jsx +106 -0
  37. package/dist/components/Wallet/WalletBalance.d.ts +4 -0
  38. package/dist/components/Wallet/WalletBalance.d.ts.map +1 -0
  39. package/dist/components/Wallet/WalletBalance.js +82 -0
  40. package/dist/components/Wallet/WalletBalance.jsx +86 -0
  41. package/dist/components/Wallet/WalletButton.d.ts +3 -0
  42. package/dist/components/Wallet/WalletButton.d.ts.map +1 -0
  43. package/dist/components/Wallet/WalletButton.js +51 -0
  44. package/dist/components/Wallet/WalletButton.jsx +53 -0
  45. package/dist/components/Wallet/WalletConnectionModal.d.ts +8 -0
  46. package/dist/components/Wallet/WalletConnectionModal.d.ts.map +1 -0
  47. package/dist/components/Wallet/WalletConnectionModal.js +150 -0
  48. package/dist/components/Wallet/WalletConnectionModal.jsx +170 -0
  49. package/dist/components/Wallet/WalletProvider.d.ts +9 -0
  50. package/dist/components/Wallet/WalletProvider.d.ts.map +1 -0
  51. package/dist/components/Wallet/WalletProvider.js +70 -0
  52. package/dist/components/Wallet/WalletProvider.jsx +75 -0
  53. package/dist/components/Wallet/index.d.ts +9 -0
  54. package/dist/components/Wallet/index.d.ts.map +1 -0
  55. package/dist/components/Wallet/index.js +8 -0
  56. package/dist/components/index.d.ts +7 -0
  57. package/dist/components/index.d.ts.map +1 -0
  58. package/dist/components/index.js +6 -0
  59. package/dist/hooks/index.d.ts +10 -0
  60. package/dist/hooks/index.d.ts.map +1 -0
  61. package/dist/hooks/index.js +9 -0
  62. package/dist/hooks/useCache.d.ts +16 -0
  63. package/dist/hooks/useCache.d.ts.map +1 -0
  64. package/dist/hooks/useCache.js +67 -0
  65. package/dist/hooks/usePolling.d.ts +16 -0
  66. package/dist/hooks/usePolling.d.ts.map +1 -0
  67. package/dist/hooks/usePolling.js +79 -0
  68. package/dist/hooks/useProgram.d.ts +14 -0
  69. package/dist/hooks/useProgram.d.ts.map +1 -0
  70. package/dist/hooks/useProgram.js +88 -0
  71. package/dist/hooks/useTokenBalance.d.ts +16 -0
  72. package/dist/hooks/useTokenBalance.d.ts.map +1 -0
  73. package/dist/hooks/useTokenBalance.js +100 -0
  74. package/dist/hooks/useVaults.d.ts +23 -0
  75. package/dist/hooks/useVaults.d.ts.map +1 -0
  76. package/dist/hooks/useVaults.js +98 -0
  77. package/dist/index.d.ts +12 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +17 -0
  80. package/dist/services/index.d.ts +7 -0
  81. package/dist/services/index.d.ts.map +1 -0
  82. package/dist/services/index.js +6 -0
  83. package/dist/services/reconciliationService.d.ts +76 -0
  84. package/dist/services/reconciliationService.d.ts.map +1 -0
  85. package/dist/services/reconciliationService.js +216 -0
  86. package/dist/services/syncService.d.ts +51 -0
  87. package/dist/services/syncService.d.ts.map +1 -0
  88. package/dist/services/syncService.js +218 -0
  89. package/dist/types/index.d.ts +201 -0
  90. package/dist/types/index.d.ts.map +1 -0
  91. package/dist/types/index.js +1 -0
  92. package/dist/utils/cacheManager.d.ts +73 -0
  93. package/dist/utils/cacheManager.d.ts.map +1 -0
  94. package/dist/utils/cacheManager.js +232 -0
  95. package/dist/utils/errorHandler.d.ts +76 -0
  96. package/dist/utils/errorHandler.d.ts.map +1 -0
  97. package/dist/utils/errorHandler.js +267 -0
  98. package/dist/utils/index.d.ts +12 -0
  99. package/dist/utils/index.d.ts.map +1 -0
  100. package/dist/utils/index.js +11 -0
  101. package/dist/utils/performanceMonitor.d.ts +75 -0
  102. package/dist/utils/performanceMonitor.d.ts.map +1 -0
  103. package/dist/utils/performanceMonitor.js +197 -0
  104. package/dist/utils/rpcRetry.d.ts +12 -0
  105. package/dist/utils/rpcRetry.d.ts.map +1 -0
  106. package/dist/utils/rpcRetry.js +47 -0
  107. package/dist/utils/supabase.d.ts +198 -0
  108. package/dist/utils/supabase.d.ts.map +1 -0
  109. package/dist/utils/supabase.js +50 -0
  110. package/dist/utils/toastService.d.ts +52 -0
  111. package/dist/utils/toastService.d.ts.map +1 -0
  112. package/dist/utils/toastService.js +139 -0
  113. package/dist/utils/tokenUtils.d.ts +33 -0
  114. package/dist/utils/tokenUtils.d.ts.map +1 -0
  115. package/dist/utils/tokenUtils.js +66 -0
  116. package/dist/utils/validation.d.ts +35 -0
  117. package/dist/utils/validation.d.ts.map +1 -0
  118. package/dist/utils/validation.js +83 -0
  119. package/package.json +45 -0
  120. package/src/components/Common/ErrorBoundary.tsx +135 -0
  121. package/src/components/Common/ErrorMessage.tsx +52 -0
  122. package/src/components/Common/Loading.tsx +56 -0
  123. package/src/components/Common/LoadingIndicator.tsx +143 -0
  124. package/src/components/Common/ProgramStatus.tsx +37 -0
  125. package/src/components/Common/Skeleton.tsx +83 -0
  126. package/src/components/Common/SkeletonScreen.tsx +166 -0
  127. package/src/components/Common/index.ts +10 -0
  128. package/src/components/Wallet/TransactionStatus.tsx +138 -0
  129. package/src/components/Wallet/WalletBalance.tsx +94 -0
  130. package/src/components/Wallet/WalletButton.tsx +65 -0
  131. package/src/components/Wallet/WalletConnectionModal.tsx +193 -0
  132. package/src/components/Wallet/WalletProvider.tsx +104 -0
  133. package/src/components/Wallet/index.ts +8 -0
  134. package/src/components/index.ts +6 -0
  135. package/src/hooks/index.ts +10 -0
  136. package/src/hooks/useCache.ts +87 -0
  137. package/src/hooks/usePolling.ts +98 -0
  138. package/src/hooks/useProgram.ts +93 -0
  139. package/src/hooks/useTokenBalance.ts +113 -0
  140. package/src/hooks/useVaults.ts +122 -0
  141. package/src/index.ts +23 -0
  142. package/src/services/index.ts +6 -0
  143. package/src/services/reconciliationService.ts +246 -0
  144. package/src/services/syncService.ts +238 -0
  145. package/src/types/index.ts +233 -0
  146. package/src/utils/cacheManager.ts +286 -0
  147. package/src/utils/errorHandler.ts +336 -0
  148. package/src/utils/index.ts +12 -0
  149. package/src/utils/performanceMonitor.ts +222 -0
  150. package/src/utils/rpcRetry.ts +55 -0
  151. package/src/utils/supabase.ts +253 -0
  152. package/src/utils/toastService.ts +166 -0
  153. package/src/utils/tokenUtils.ts +75 -0
  154. package/src/utils/validation.ts +107 -0
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Loading Indicator Component
3
+ * Displays loading feedback appropriate to context
4
+ * Requirements: 5.2, 5.5
5
+ */
6
+ import React from 'react';
7
+ import styled, { keyframes } from 'styled-components';
8
+ const spin = keyframes `
9
+ to { transform: rotate(360deg); }
10
+ `;
11
+ const dots = keyframes `
12
+ 0%, 20% {
13
+ content: '.';
14
+ }
15
+ 40% {
16
+ content: '..';
17
+ }
18
+ 60%, 100% {
19
+ content: '...';
20
+ }
21
+ `;
22
+ const Container = styled.div `
23
+ display: flex;
24
+ flex-direction: column;
25
+ align-items: center;
26
+ justify-content: center;
27
+ gap: var(--spacing-md, 1rem);
28
+ padding: var(--spacing-lg, 1.5rem);
29
+ `;
30
+ const Spinner = styled.div `
31
+ width: ${props => {
32
+ switch (props.size) {
33
+ case 'small': return '24px';
34
+ case 'large': return '64px';
35
+ default: return '48px';
36
+ }
37
+ }};
38
+ height: ${props => {
39
+ switch (props.size) {
40
+ case 'small': return '24px';
41
+ case 'large': return '64px';
42
+ default: return '48px';
43
+ }
44
+ }};
45
+ border: 4px solid var(--color-border, #e5e7eb);
46
+ border-top-color: var(--color-primary, #6a8102);
47
+ border-radius: 50%;
48
+ animation: ${spin} 1s linear infinite;
49
+ `;
50
+ const ProgressBarContainer = styled.div `
51
+ width: 100%;
52
+ max-width: 300px;
53
+ height: 8px;
54
+ background: var(--color-border, #e5e7eb);
55
+ border-radius: var(--border-radius-md, 0.375rem);
56
+ overflow: hidden;
57
+ `;
58
+ const ProgressBar = styled.div `
59
+ height: 100%;
60
+ width: ${props => props.progress}%;
61
+ background: linear-gradient(90deg, var(--color-primary, #6a8102), var(--color-secondary, #ffc107));
62
+ border-radius: var(--border-radius-md, 0.375rem);
63
+ transition: width 0.3s ease;
64
+ `;
65
+ const Dots = styled.div `
66
+ font-size: 1.5rem;
67
+ color: var(--color-primary, #6a8102);
68
+
69
+ &::after {
70
+ content: '.';
71
+ animation: ${dots} 1.5s steps(4, end) infinite;
72
+ }
73
+ `;
74
+ const Message = styled.p `
75
+ color: var(--color-text-secondary, #6b7280);
76
+ font-size: 0.875rem;
77
+ margin: 0;
78
+ text-align: center;
79
+ `;
80
+ const ProgressText = styled.span `
81
+ color: var(--color-text-secondary, #6b7280);
82
+ font-size: 0.75rem;
83
+ font-weight: 600;
84
+ margin-top: var(--spacing-xs, 0.25rem);
85
+ `;
86
+ export const LoadingIndicator = ({ type, size = 'medium', message, progress, }) => {
87
+ const renderIndicator = () => {
88
+ switch (type) {
89
+ case 'spinner':
90
+ return <Spinner size={size}/>;
91
+ case 'progress':
92
+ return (<div style={{ width: '100%', maxWidth: '300px' }}>
93
+ <ProgressBarContainer>
94
+ <ProgressBar progress={progress || 0}/>
95
+ </ProgressBarContainer>
96
+ {progress !== undefined && (<ProgressText>{Math.round(progress)}%</ProgressText>)}
97
+ </div>);
98
+ case 'dots':
99
+ return <Dots />;
100
+ default:
101
+ return null;
102
+ }
103
+ };
104
+ return (<Container>
105
+ {renderIndicator()}
106
+ {message && <Message>{message}</Message>}
107
+ </Container>);
108
+ };
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare const ProgramStatus: React.FC;
3
+ //# sourceMappingURL=ProgramStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProgramStatus.d.ts","sourceRoot":"","sources":["../../../src/components/Common/ProgramStatus.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAMzC,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EA0BjC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { useEffect } from 'react';
3
+ import styled from 'styled-components';
4
+ import { useProgram } from '../../hooks/useProgram';
5
+ import { ErrorMessage } from './ErrorMessage';
6
+ import toast from 'react-hot-toast';
7
+ export const ProgramStatus = () => {
8
+ const { program, idl, idlError, programId } = useProgram();
9
+ const [showError, setShowError] = React.useState(false);
10
+ useEffect(() => {
11
+ if (idlError) {
12
+ setShowError(true);
13
+ toast.error(`Failed to load program: ${idlError}`, {
14
+ duration: 5000,
15
+ });
16
+ }
17
+ }, [idlError]);
18
+ // Don't show anything if program is loading or ready
19
+ if (!idlError) {
20
+ return null;
21
+ }
22
+ return (_jsx(Container, { children: _jsx(ErrorMessage, { message: `Failed to load program contract. Please refresh the page. Error: ${idlError}`, onRetry: () => window.location.reload() }) }));
23
+ };
24
+ const Container = styled.div `
25
+ margin: var(--spacing-md, 1rem) 0;
26
+ `;
@@ -0,0 +1,27 @@
1
+ import React, { useEffect } from 'react';
2
+ import styled from 'styled-components';
3
+ import { useProgram } from '../../hooks/useProgram';
4
+ import { ErrorMessage } from './ErrorMessage';
5
+ import toast from 'react-hot-toast';
6
+ export const ProgramStatus = () => {
7
+ const { program, idl, idlError, programId } = useProgram();
8
+ const [showError, setShowError] = React.useState(false);
9
+ useEffect(() => {
10
+ if (idlError) {
11
+ setShowError(true);
12
+ toast.error(`Failed to load program: ${idlError}`, {
13
+ duration: 5000,
14
+ });
15
+ }
16
+ }, [idlError]);
17
+ // Don't show anything if program is loading or ready
18
+ if (!idlError) {
19
+ return null;
20
+ }
21
+ return (<Container>
22
+ <ErrorMessage message={`Failed to load program contract. Please refresh the page. Error: ${idlError}`} onRetry={() => window.location.reload()}/>
23
+ </Container>);
24
+ };
25
+ const Container = styled.div `
26
+ margin: var(--spacing-md, 1rem) 0;
27
+ `;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Skeleton Screen Components
3
+ * Requirements: 11.3 - Loading states with skeleton screens for better perceived performance
4
+ */
5
+ import React from 'react';
6
+ export declare const SkeletonCard: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "height" | "width"> & {
7
+ width?: string;
8
+ height?: string;
9
+ }, "ref"> & {
10
+ ref?: React.Ref<HTMLDivElement>;
11
+ }, never>> & string;
12
+ export declare const SkeletonText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "height" | "width"> & {
13
+ width?: string;
14
+ height?: string;
15
+ }, "ref"> & {
16
+ ref?: React.Ref<HTMLDivElement>;
17
+ }, never>> & string;
18
+ export declare const SkeletonTitle: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "height" | "width"> & {
19
+ width?: string;
20
+ height?: string;
21
+ }, "ref"> & {
22
+ ref?: React.Ref<HTMLDivElement>;
23
+ }, never>> & string;
24
+ export declare const SkeletonButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "height" | "width"> & {
25
+ width?: string;
26
+ height?: string;
27
+ }, "ref"> & {
28
+ ref?: React.Ref<HTMLDivElement>;
29
+ }, never>> & string;
30
+ export declare const SkeletonAvatar: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "height" | "width"> & {
31
+ width?: string;
32
+ height?: string;
33
+ }, "ref"> & {
34
+ ref?: React.Ref<HTMLDivElement>;
35
+ }, never>> & string;
36
+ export declare const VaultCardSkeleton: React.FC;
37
+ export declare const StatsSkeleton: React.FC;
38
+ export declare const ProfileSkeleton: React.FC;
39
+ //# sourceMappingURL=Skeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Skeleton.d.ts","sourceRoot":"","sources":["../../../src/components/Common/Skeleton.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AA0B1B,eAAO,MAAM,YAAY;YAdiB,MAAM;aAAW,MAAM;;;mBAiBhE,CAAC;AAEF,eAAO,MAAM,YAAY;YAnBiB,MAAM;aAAW,MAAM;;;mBA0BhE,CAAC;AAEF,eAAO,MAAM,aAAa;YA5BgB,MAAM;aAAW,MAAM;;;mBAgChE,CAAC;AAEF,eAAO,MAAM,cAAc;YAlCe,MAAM;aAAW,MAAM;;;mBAsChE,CAAC;AAEF,eAAO,MAAM,cAAc;YAxCe,MAAM;aAAW,MAAM;;;mBA4ChE,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAErC,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAOjC,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAOnC,CAAC"}
@@ -0,0 +1,53 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import styled, { keyframes } from 'styled-components';
3
+ const shimmer = keyframes `
4
+ 0% {
5
+ background-position: -1000px 0;
6
+ }
7
+ 100% {
8
+ background-position: 1000px 0;
9
+ }
10
+ `;
11
+ const SkeletonBase = styled.div `
12
+ background: linear-gradient(
13
+ 90deg,
14
+ var(--color-surface, #f9fafb) 0%,
15
+ var(--color-border, #e5e7eb) 50%,
16
+ var(--color-surface, #f9fafb) 100%
17
+ );
18
+ background-size: 1000px 100%;
19
+ animation: ${shimmer} 2s infinite;
20
+ border-radius: var(--border-radius-md, 0.375rem);
21
+ width: ${props => props.width || '100%'};
22
+ height: ${props => props.height || '20px'};
23
+ `;
24
+ export const SkeletonCard = styled(SkeletonBase) `
25
+ height: 200px;
26
+ margin-bottom: var(--spacing-md, 1rem);
27
+ `;
28
+ export const SkeletonText = styled(SkeletonBase) `
29
+ height: 16px;
30
+ margin-bottom: var(--spacing-xs, 0.25rem);
31
+
32
+ &:last-child {
33
+ margin-bottom: 0;
34
+ }
35
+ `;
36
+ export const SkeletonTitle = styled(SkeletonBase) `
37
+ height: 24px;
38
+ width: 60%;
39
+ margin-bottom: var(--spacing-md, 1rem);
40
+ `;
41
+ export const SkeletonButton = styled(SkeletonBase) `
42
+ height: 40px;
43
+ width: 120px;
44
+ border-radius: var(--border-radius-md, 0.375rem);
45
+ `;
46
+ export const SkeletonAvatar = styled(SkeletonBase) `
47
+ width: 64px;
48
+ height: 64px;
49
+ border-radius: 50%;
50
+ `;
51
+ export const VaultCardSkeleton = () => (_jsx(SkeletonCard, {}));
52
+ export const StatsSkeleton = () => (_jsxs(_Fragment, { children: [_jsx(SkeletonTitle, {}), _jsx(SkeletonText, { width: "100%" }), _jsx(SkeletonText, { width: "80%" }), _jsx(SkeletonText, { width: "90%" })] }));
53
+ export const ProfileSkeleton = () => (_jsxs(_Fragment, { children: [_jsx(SkeletonAvatar, { width: "80px", height: "80px" }), _jsx(SkeletonTitle, { width: "40%" }), _jsx(SkeletonText, { width: "60%" }), _jsx(SkeletonText, { width: "50%" })] }));
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Skeleton Screen Components
3
+ * Requirements: 11.3 - Loading states with skeleton screens for better perceived performance
4
+ */
5
+ import React from 'react';
6
+ import styled, { keyframes } from 'styled-components';
7
+ const shimmer = keyframes `
8
+ 0% {
9
+ background-position: -1000px 0;
10
+ }
11
+ 100% {
12
+ background-position: 1000px 0;
13
+ }
14
+ `;
15
+ const SkeletonBase = styled.div `
16
+ background: linear-gradient(
17
+ 90deg,
18
+ var(--color-surface, #f9fafb) 0%,
19
+ var(--color-border, #e5e7eb) 50%,
20
+ var(--color-surface, #f9fafb) 100%
21
+ );
22
+ background-size: 1000px 100%;
23
+ animation: ${shimmer} 2s infinite;
24
+ border-radius: var(--border-radius-md, 0.375rem);
25
+ width: ${props => props.width || '100%'};
26
+ height: ${props => props.height || '20px'};
27
+ `;
28
+ export const SkeletonCard = styled(SkeletonBase) `
29
+ height: 200px;
30
+ margin-bottom: var(--spacing-md, 1rem);
31
+ `;
32
+ export const SkeletonText = styled(SkeletonBase) `
33
+ height: 16px;
34
+ margin-bottom: var(--spacing-xs, 0.25rem);
35
+
36
+ &:last-child {
37
+ margin-bottom: 0;
38
+ }
39
+ `;
40
+ export const SkeletonTitle = styled(SkeletonBase) `
41
+ height: 24px;
42
+ width: 60%;
43
+ margin-bottom: var(--spacing-md, 1rem);
44
+ `;
45
+ export const SkeletonButton = styled(SkeletonBase) `
46
+ height: 40px;
47
+ width: 120px;
48
+ border-radius: var(--border-radius-md, 0.375rem);
49
+ `;
50
+ export const SkeletonAvatar = styled(SkeletonBase) `
51
+ width: 64px;
52
+ height: 64px;
53
+ border-radius: 50%;
54
+ `;
55
+ export const VaultCardSkeleton = () => (<SkeletonCard />);
56
+ export const StatsSkeleton = () => (<>
57
+ <SkeletonTitle />
58
+ <SkeletonText width="100%"/>
59
+ <SkeletonText width="80%"/>
60
+ <SkeletonText width="90%"/>
61
+ </>);
62
+ export const ProfileSkeleton = () => (<>
63
+ <SkeletonAvatar width="80px" height="80px"/>
64
+ <SkeletonTitle width="40%"/>
65
+ <SkeletonText width="60%"/>
66
+ <SkeletonText width="50%"/>
67
+ </>);
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Skeleton Screen Component
3
+ * Loading placeholder that mimics content structure
4
+ * Requirements: 5.1
5
+ */
6
+ import React from 'react';
7
+ export type SkeletonVariant = 'card' | 'table' | 'chart' | 'list' | 'text';
8
+ export type SkeletonAnimation = 'pulse' | 'wave' | 'none';
9
+ interface SkeletonScreenProps {
10
+ variant: SkeletonVariant;
11
+ count?: number;
12
+ height?: string;
13
+ width?: string;
14
+ animation?: SkeletonAnimation;
15
+ }
16
+ export declare const SkeletonScreen: React.FC<SkeletonScreenProps>;
17
+ export {};
18
+ //# sourceMappingURL=SkeletonScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SkeletonScreen.d.ts","sourceRoot":"","sources":["../../../src/components/Common/SkeletonScreen.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAC3E,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1D,UAAU,mBAAmB;IAC3B,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B;AA+FD,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAqDxD,CAAC"}
@@ -0,0 +1,98 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import styled, { keyframes } from 'styled-components';
3
+ const pulse = keyframes `
4
+ 0%, 100% {
5
+ opacity: 1;
6
+ }
7
+ 50% {
8
+ opacity: 0.5;
9
+ }
10
+ `;
11
+ const wave = keyframes `
12
+ 0% {
13
+ transform: translateX(-100%);
14
+ }
15
+ 50% {
16
+ transform: translateX(100%);
17
+ }
18
+ 100% {
19
+ transform: translateX(100%);
20
+ }
21
+ `;
22
+ const SkeletonBase = styled.div `
23
+ background: linear-gradient(
24
+ 90deg,
25
+ var(--color-border, #e5e7eb) 0%,
26
+ var(--color-surface, #f9fafb) 50%,
27
+ var(--color-border, #e5e7eb) 100%
28
+ );
29
+ background-size: 200% 100%;
30
+ border-radius: var(--border-radius-md, 0.375rem);
31
+
32
+ ${props => {
33
+ switch (props.$animation) {
34
+ case 'pulse':
35
+ return `animation: ${pulse} 1.5s ease-in-out infinite;`;
36
+ case 'wave':
37
+ return `animation: ${wave} 1.5s ease-in-out infinite;`;
38
+ default:
39
+ return '';
40
+ }
41
+ }}
42
+ `;
43
+ const CardSkeleton = styled(SkeletonBase) `
44
+ height: ${props => props.$height || '200px'};
45
+ width: ${props => props.$width || '100%'};
46
+ margin-bottom: var(--spacing-md, 1rem);
47
+ `;
48
+ const TableSkeleton = styled.div `
49
+ display: flex;
50
+ flex-direction: column;
51
+ gap: var(--spacing-sm, 0.5rem);
52
+ `;
53
+ const TableRowSkeleton = styled(SkeletonBase) `
54
+ height: ${props => props.$height || '48px'};
55
+ width: 100%;
56
+ `;
57
+ const ChartSkeleton = styled(SkeletonBase) `
58
+ height: ${props => props.$height || '300px'};
59
+ width: ${props => props.$width || '100%'};
60
+ border-radius: var(--border-radius-lg, 0.5rem);
61
+ `;
62
+ const ListSkeleton = styled.div `
63
+ display: flex;
64
+ flex-direction: column;
65
+ gap: var(--spacing-md, 1rem);
66
+ `;
67
+ const ListItemSkeleton = styled(SkeletonBase) `
68
+ height: ${props => props.$height || '60px'};
69
+ width: 100%;
70
+ `;
71
+ const TextSkeleton = styled(SkeletonBase) `
72
+ height: ${props => props.$height || '1em'};
73
+ width: ${props => props.$width || '100%'};
74
+ margin-bottom: var(--spacing-xs, 0.25rem);
75
+
76
+ &:last-child {
77
+ margin-bottom: 0;
78
+ }
79
+ `;
80
+ export const SkeletonScreen = ({ variant, count = 1, height, width, animation = 'pulse', }) => {
81
+ const renderSkeleton = () => {
82
+ switch (variant) {
83
+ case 'card':
84
+ return Array.from({ length: count }).map((_, i) => (_jsx(CardSkeleton, { "$animation": animation, "$height": height, "$width": width }, i)));
85
+ case 'table':
86
+ return (_jsx(TableSkeleton, { children: Array.from({ length: count }).map((_, i) => (_jsx(TableRowSkeleton, { "$animation": animation, "$height": height }, i))) }));
87
+ case 'chart':
88
+ return (_jsx(ChartSkeleton, { "$animation": animation, "$height": height, "$width": width }));
89
+ case 'list':
90
+ return (_jsx(ListSkeleton, { children: Array.from({ length: count }).map((_, i) => (_jsx(ListItemSkeleton, { "$animation": animation, "$height": height }, i))) }));
91
+ case 'text':
92
+ return Array.from({ length: count }).map((_, i) => (_jsx(TextSkeleton, { "$animation": animation, "$height": height, "$width": i === count - 1 ? '80%' : width }, i)));
93
+ default:
94
+ return null;
95
+ }
96
+ };
97
+ return _jsx(_Fragment, { children: renderSkeleton() });
98
+ };
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Skeleton Screen Component
3
+ * Loading placeholder that mimics content structure
4
+ * Requirements: 5.1
5
+ */
6
+ import React from 'react';
7
+ import styled, { keyframes } from 'styled-components';
8
+ const pulse = keyframes `
9
+ 0%, 100% {
10
+ opacity: 1;
11
+ }
12
+ 50% {
13
+ opacity: 0.5;
14
+ }
15
+ `;
16
+ const wave = keyframes `
17
+ 0% {
18
+ transform: translateX(-100%);
19
+ }
20
+ 50% {
21
+ transform: translateX(100%);
22
+ }
23
+ 100% {
24
+ transform: translateX(100%);
25
+ }
26
+ `;
27
+ const SkeletonBase = styled.div `
28
+ background: linear-gradient(
29
+ 90deg,
30
+ var(--color-border, #e5e7eb) 0%,
31
+ var(--color-surface, #f9fafb) 50%,
32
+ var(--color-border, #e5e7eb) 100%
33
+ );
34
+ background-size: 200% 100%;
35
+ border-radius: var(--border-radius-md, 0.375rem);
36
+
37
+ ${props => {
38
+ switch (props.$animation) {
39
+ case 'pulse':
40
+ return `animation: ${pulse} 1.5s ease-in-out infinite;`;
41
+ case 'wave':
42
+ return `animation: ${wave} 1.5s ease-in-out infinite;`;
43
+ default:
44
+ return '';
45
+ }
46
+ }}
47
+ `;
48
+ const CardSkeleton = styled(SkeletonBase) `
49
+ height: ${props => props.$height || '200px'};
50
+ width: ${props => props.$width || '100%'};
51
+ margin-bottom: var(--spacing-md, 1rem);
52
+ `;
53
+ const TableSkeleton = styled.div `
54
+ display: flex;
55
+ flex-direction: column;
56
+ gap: var(--spacing-sm, 0.5rem);
57
+ `;
58
+ const TableRowSkeleton = styled(SkeletonBase) `
59
+ height: ${props => props.$height || '48px'};
60
+ width: 100%;
61
+ `;
62
+ const ChartSkeleton = styled(SkeletonBase) `
63
+ height: ${props => props.$height || '300px'};
64
+ width: ${props => props.$width || '100%'};
65
+ border-radius: var(--border-radius-lg, 0.5rem);
66
+ `;
67
+ const ListSkeleton = styled.div `
68
+ display: flex;
69
+ flex-direction: column;
70
+ gap: var(--spacing-md, 1rem);
71
+ `;
72
+ const ListItemSkeleton = styled(SkeletonBase) `
73
+ height: ${props => props.$height || '60px'};
74
+ width: 100%;
75
+ `;
76
+ const TextSkeleton = styled(SkeletonBase) `
77
+ height: ${props => props.$height || '1em'};
78
+ width: ${props => props.$width || '100%'};
79
+ margin-bottom: var(--spacing-xs, 0.25rem);
80
+
81
+ &:last-child {
82
+ margin-bottom: 0;
83
+ }
84
+ `;
85
+ export const SkeletonScreen = ({ variant, count = 1, height, width, animation = 'pulse', }) => {
86
+ const renderSkeleton = () => {
87
+ switch (variant) {
88
+ case 'card':
89
+ return Array.from({ length: count }).map((_, i) => (<CardSkeleton key={i} $animation={animation} $height={height} $width={width}/>));
90
+ case 'table':
91
+ return (<TableSkeleton>
92
+ {Array.from({ length: count }).map((_, i) => (<TableRowSkeleton key={i} $animation={animation} $height={height}/>))}
93
+ </TableSkeleton>);
94
+ case 'chart':
95
+ return (<ChartSkeleton $animation={animation} $height={height} $width={width}/>);
96
+ case 'list':
97
+ return (<ListSkeleton>
98
+ {Array.from({ length: count }).map((_, i) => (<ListItemSkeleton key={i} $animation={animation} $height={height}/>))}
99
+ </ListSkeleton>);
100
+ case 'text':
101
+ return Array.from({ length: count }).map((_, i) => (<TextSkeleton key={i} $animation={animation} $height={height} $width={i === count - 1 ? '80%' : width} // Last line shorter
102
+ />));
103
+ default:
104
+ return null;
105
+ }
106
+ };
107
+ return <>{renderSkeleton()}</>;
108
+ };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Common Components Index
3
+ */
4
+ export * from './ErrorBoundary';
5
+ export * from './ErrorMessage';
6
+ export * from './Loading';
7
+ export * from './LoadingIndicator';
8
+ export * from './Skeleton';
9
+ export * from './SkeletonScreen';
10
+ export * from './ProgramStatus';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Common/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Common Components Index
3
+ */
4
+ export * from './ErrorBoundary';
5
+ export * from './ErrorMessage';
6
+ export * from './Loading';
7
+ export * from './LoadingIndicator';
8
+ export * from './Skeleton';
9
+ export * from './SkeletonScreen';
10
+ export * from './ProgramStatus';
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ interface TransactionStatusProps {
3
+ status: 'pending' | 'confirmed' | 'failed';
4
+ message: string;
5
+ signature?: string;
6
+ explorerUrl?: string;
7
+ network?: string;
8
+ }
9
+ declare const TransactionStatus: React.FC<TransactionStatusProps>;
10
+ export default TransactionStatus;
11
+ //# sourceMappingURL=TransactionStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransactionStatus.d.ts","sourceRoot":"","sources":["../../../src/components/Wallet/TransactionStatus.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AA4E1B,UAAU,sBAAsB;IAC9B,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,QAAA,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAmDvD,CAAC;AAEF,eAAe,iBAAiB,CAAC"}