warqadui 0.0.8 → 0.0.11

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 (170) hide show
  1. package/{packages/ui/dist → dist}/index.d.mts +100 -12
  2. package/{packages/ui/dist → dist}/index.d.ts +100 -12
  3. package/dist/index.js +3276 -0
  4. package/dist/index.mjs +3237 -0
  5. package/dist/styles.js +26 -0
  6. package/dist/styles.mjs +24 -0
  7. package/package.json +60 -10
  8. package/.vscode/settings.json +0 -3
  9. package/apps/dev-app/.env +0 -1
  10. package/apps/dev-app/errors.log +0 -0
  11. package/apps/dev-app/index.html +0 -12
  12. package/apps/dev-app/node_modules/.vite/deps/@tanstack_react-table.js +0 -3254
  13. package/apps/dev-app/node_modules/.vite/deps/@tanstack_react-table.js.map +0 -7
  14. package/apps/dev-app/node_modules/.vite/deps/_metadata.json +0 -166
  15. package/apps/dev-app/node_modules/.vite/deps/antd.js +0 -108982
  16. package/apps/dev-app/node_modules/.vite/deps/antd.js.map +0 -7
  17. package/apps/dev-app/node_modules/.vite/deps/axios.js +0 -2751
  18. package/apps/dev-app/node_modules/.vite/deps/axios.js.map +0 -7
  19. package/apps/dev-app/node_modules/.vite/deps/chunk-5OG7DCD7.js +0 -41
  20. package/apps/dev-app/node_modules/.vite/deps/chunk-5OG7DCD7.js.map +0 -7
  21. package/apps/dev-app/node_modules/.vite/deps/chunk-DC5AMYBS.js +0 -39
  22. package/apps/dev-app/node_modules/.vite/deps/chunk-DC5AMYBS.js.map +0 -7
  23. package/apps/dev-app/node_modules/.vite/deps/chunk-DKXRQMOD.js +0 -135
  24. package/apps/dev-app/node_modules/.vite/deps/chunk-DKXRQMOD.js.map +0 -7
  25. package/apps/dev-app/node_modules/.vite/deps/chunk-EL47BWQR.js +0 -37
  26. package/apps/dev-app/node_modules/.vite/deps/chunk-EL47BWQR.js.map +0 -7
  27. package/apps/dev-app/node_modules/.vite/deps/chunk-HHL3MHGV.js +0 -288
  28. package/apps/dev-app/node_modules/.vite/deps/chunk-HHL3MHGV.js.map +0 -7
  29. package/apps/dev-app/node_modules/.vite/deps/chunk-IGGUWUPT.js +0 -60
  30. package/apps/dev-app/node_modules/.vite/deps/chunk-IGGUWUPT.js.map +0 -7
  31. package/apps/dev-app/node_modules/.vite/deps/chunk-IGXZPJXT.js +0 -928
  32. package/apps/dev-app/node_modules/.vite/deps/chunk-IGXZPJXT.js.map +0 -7
  33. package/apps/dev-app/node_modules/.vite/deps/chunk-L2GCM37S.js +0 -21628
  34. package/apps/dev-app/node_modules/.vite/deps/chunk-L2GCM37S.js.map +0 -7
  35. package/apps/dev-app/node_modules/.vite/deps/chunk-M7DZDBHW.js +0 -14
  36. package/apps/dev-app/node_modules/.vite/deps/chunk-M7DZDBHW.js.map +0 -7
  37. package/apps/dev-app/node_modules/.vite/deps/chunk-S54SBVCU.js +0 -1906
  38. package/apps/dev-app/node_modules/.vite/deps/chunk-S54SBVCU.js.map +0 -7
  39. package/apps/dev-app/node_modules/.vite/deps/chunk-WFNHCR67.js +0 -21
  40. package/apps/dev-app/node_modules/.vite/deps/chunk-WFNHCR67.js.map +0 -7
  41. package/apps/dev-app/node_modules/.vite/deps/clsx.js +0 -10
  42. package/apps/dev-app/node_modules/.vite/deps/clsx.js.map +0 -7
  43. package/apps/dev-app/node_modules/.vite/deps/dayjs.js +0 -6
  44. package/apps/dev-app/node_modules/.vite/deps/dayjs.js.map +0 -7
  45. package/apps/dev-app/node_modules/.vite/deps/dayjs_plugin_customParseFormat.js +0 -6
  46. package/apps/dev-app/node_modules/.vite/deps/dayjs_plugin_customParseFormat.js.map +0 -7
  47. package/apps/dev-app/node_modules/.vite/deps/framer-motion.js +0 -12388
  48. package/apps/dev-app/node_modules/.vite/deps/framer-motion.js.map +0 -7
  49. package/apps/dev-app/node_modules/.vite/deps/html2canvas-pro.js +0 -9713
  50. package/apps/dev-app/node_modules/.vite/deps/html2canvas-pro.js.map +0 -7
  51. package/apps/dev-app/node_modules/.vite/deps/html2canvas.esm-IYRWPPEI.js +0 -7808
  52. package/apps/dev-app/node_modules/.vite/deps/html2canvas.esm-IYRWPPEI.js.map +0 -7
  53. package/apps/dev-app/node_modules/.vite/deps/index.es-3WTXOFZ2.js +0 -10392
  54. package/apps/dev-app/node_modules/.vite/deps/index.es-3WTXOFZ2.js.map +0 -7
  55. package/apps/dev-app/node_modules/.vite/deps/jspdf.js +0 -14806
  56. package/apps/dev-app/node_modules/.vite/deps/jspdf.js.map +0 -7
  57. package/apps/dev-app/node_modules/.vite/deps/lucide-react.js +0 -31586
  58. package/apps/dev-app/node_modules/.vite/deps/lucide-react.js.map +0 -7
  59. package/apps/dev-app/node_modules/.vite/deps/package.json +0 -3
  60. package/apps/dev-app/node_modules/.vite/deps/purify.es-JNLDEIMX.js +0 -1029
  61. package/apps/dev-app/node_modules/.vite/deps/purify.es-JNLDEIMX.js.map +0 -7
  62. package/apps/dev-app/node_modules/.vite/deps/react-dom.js +0 -7
  63. package/apps/dev-app/node_modules/.vite/deps/react-dom.js.map +0 -7
  64. package/apps/dev-app/node_modules/.vite/deps/react-dom_client.js +0 -8
  65. package/apps/dev-app/node_modules/.vite/deps/react-dom_client.js.map +0 -7
  66. package/apps/dev-app/node_modules/.vite/deps/react-hook-form.js +0 -2233
  67. package/apps/dev-app/node_modules/.vite/deps/react-hook-form.js.map +0 -7
  68. package/apps/dev-app/node_modules/.vite/deps/react-phone-number-input.js +0 -9307
  69. package/apps/dev-app/node_modules/.vite/deps/react-phone-number-input.js.map +0 -7
  70. package/apps/dev-app/node_modules/.vite/deps/react-router-dom.js +0 -14234
  71. package/apps/dev-app/node_modules/.vite/deps/react-router-dom.js.map +0 -7
  72. package/apps/dev-app/node_modules/.vite/deps/react.js +0 -6
  73. package/apps/dev-app/node_modules/.vite/deps/react.js.map +0 -7
  74. package/apps/dev-app/node_modules/.vite/deps/react_jsx-dev-runtime.js +0 -913
  75. package/apps/dev-app/node_modules/.vite/deps/react_jsx-dev-runtime.js.map +0 -7
  76. package/apps/dev-app/node_modules/.vite/deps/react_jsx-runtime.js +0 -7
  77. package/apps/dev-app/node_modules/.vite/deps/react_jsx-runtime.js.map +0 -7
  78. package/apps/dev-app/node_modules/.vite/deps/tailwind-merge.js +0 -2534
  79. package/apps/dev-app/node_modules/.vite/deps/tailwind-merge.js.map +0 -7
  80. package/apps/dev-app/node_modules/tailwindcss/LICENSE +0 -21
  81. package/apps/dev-app/node_modules/tailwindcss/README.md +0 -36
  82. package/apps/dev-app/node_modules/tailwindcss/dist/chunk-L5IEUH3R.mjs +0 -38
  83. package/apps/dev-app/node_modules/tailwindcss/dist/chunk-UWKE2Z6N.mjs +0 -1
  84. package/apps/dev-app/node_modules/tailwindcss/dist/chunk-X4GG3EDV.mjs +0 -1
  85. package/apps/dev-app/node_modules/tailwindcss/dist/colors-C__qRT83.d.ts +0 -347
  86. package/apps/dev-app/node_modules/tailwindcss/dist/colors.d.mts +0 -347
  87. package/apps/dev-app/node_modules/tailwindcss/dist/colors.d.ts +0 -5
  88. package/apps/dev-app/node_modules/tailwindcss/dist/colors.js +0 -1
  89. package/apps/dev-app/node_modules/tailwindcss/dist/colors.mjs +0 -1
  90. package/apps/dev-app/node_modules/tailwindcss/dist/default-theme.d.mts +0 -1199
  91. package/apps/dev-app/node_modules/tailwindcss/dist/default-theme.d.ts +0 -1199
  92. package/apps/dev-app/node_modules/tailwindcss/dist/default-theme.js +0 -1
  93. package/apps/dev-app/node_modules/tailwindcss/dist/default-theme.mjs +0 -1
  94. package/apps/dev-app/node_modules/tailwindcss/dist/flatten-color-palette.d.mts +0 -6
  95. package/apps/dev-app/node_modules/tailwindcss/dist/flatten-color-palette.d.ts +0 -6
  96. package/apps/dev-app/node_modules/tailwindcss/dist/flatten-color-palette.js +0 -3
  97. package/apps/dev-app/node_modules/tailwindcss/dist/flatten-color-palette.mjs +0 -1
  98. package/apps/dev-app/node_modules/tailwindcss/dist/lib.d.mts +0 -378
  99. package/apps/dev-app/node_modules/tailwindcss/dist/lib.d.ts +0 -3
  100. package/apps/dev-app/node_modules/tailwindcss/dist/lib.js +0 -38
  101. package/apps/dev-app/node_modules/tailwindcss/dist/lib.mjs +0 -1
  102. package/apps/dev-app/node_modules/tailwindcss/dist/plugin.d.mts +0 -11
  103. package/apps/dev-app/node_modules/tailwindcss/dist/plugin.d.ts +0 -134
  104. package/apps/dev-app/node_modules/tailwindcss/dist/plugin.js +0 -1
  105. package/apps/dev-app/node_modules/tailwindcss/dist/plugin.mjs +0 -1
  106. package/apps/dev-app/node_modules/tailwindcss/dist/resolve-config-B4yBzhca.d.ts +0 -29
  107. package/apps/dev-app/node_modules/tailwindcss/dist/resolve-config-QUZ9b-Gn.d.mts +0 -190
  108. package/apps/dev-app/node_modules/tailwindcss/dist/types-CJYAW1ql.d.mts +0 -128
  109. package/apps/dev-app/node_modules/tailwindcss/index.css +0 -944
  110. package/apps/dev-app/node_modules/tailwindcss/package.json +0 -89
  111. package/apps/dev-app/node_modules/tailwindcss/preflight.css +0 -393
  112. package/apps/dev-app/node_modules/tailwindcss/theme.css +0 -510
  113. package/apps/dev-app/node_modules/tailwindcss/utilities.css +0 -1
  114. package/apps/dev-app/package.json +0 -34
  115. package/apps/dev-app/src/App.tsx +0 -74
  116. package/apps/dev-app/src/index.css +0 -18
  117. package/apps/dev-app/src/main.tsx +0 -18
  118. package/apps/dev-app/src/pages/Buttons.tsx +0 -122
  119. package/apps/dev-app/src/pages/DataTable.tsx +0 -208
  120. package/apps/dev-app/src/pages/Fields.tsx +0 -342
  121. package/apps/dev-app/src/pages/Modals.tsx +0 -151
  122. package/apps/dev-app/src/pages/Spins.tsx +0 -161
  123. package/apps/dev-app/ts_errors.txt +0 -0
  124. package/apps/dev-app/tsconfig.json +0 -25
  125. package/apps/dev-app/tsconfig.node.json +0 -10
  126. package/apps/dev-app/vite.config.ts +0 -11
  127. package/packages/ui/dist/index.js +0 -2296
  128. package/packages/ui/dist/index.mjs +0 -2249
  129. package/packages/ui/dist/styles.js +0 -26
  130. package/packages/ui/dist/styles.mjs +0 -24
  131. package/packages/ui/log.txt +0 -0
  132. package/packages/ui/package.json +0 -70
  133. package/packages/ui/postcss.config.js +0 -6
  134. package/packages/ui/src/components/Button.tsx +0 -85
  135. package/packages/ui/src/components/Card.tsx +0 -97
  136. package/packages/ui/src/components/CodeBlock.tsx +0 -53
  137. package/packages/ui/src/components/DashboardLayout.tsx +0 -442
  138. package/packages/ui/src/components/Fields/Input.tsx +0 -191
  139. package/packages/ui/src/components/Fields/PhoneInput.tsx +0 -134
  140. package/packages/ui/src/components/Fields/date.tsx +0 -165
  141. package/packages/ui/src/components/Fields/index.tsx +0 -17
  142. package/packages/ui/src/components/Fields/searchApi.tsx +0 -479
  143. package/packages/ui/src/components/Fields/select.tsx +0 -131
  144. package/packages/ui/src/components/Fields/textArea.tsx +0 -121
  145. package/packages/ui/src/components/LoadingBox.tsx +0 -11
  146. package/packages/ui/src/components/PageHeader.tsx +0 -34
  147. package/packages/ui/src/components/ThemeToggle.tsx +0 -35
  148. package/packages/ui/src/components/modal/Modal.tsx +0 -81
  149. package/packages/ui/src/components/spins/ClassicSpin.tsx +0 -18
  150. package/packages/ui/src/components/spins/LoadingSpin.tsx +0 -45
  151. package/packages/ui/src/components/spins/OverlaySpin.tsx +0 -10
  152. package/packages/ui/src/components/spins/index.tsx +0 -13
  153. package/packages/ui/src/components/tables/DataTable.tsx +0 -261
  154. package/packages/ui/src/components/tables/index.ts +0 -1
  155. package/packages/ui/src/hooks/Fetches/useApis.tsx +0 -197
  156. package/packages/ui/src/hooks/ThemeContext.tsx +0 -56
  157. package/packages/ui/src/hooks/useModal.tsx +0 -38
  158. package/packages/ui/src/hooks/useTheme.ts +0 -34
  159. package/packages/ui/src/index.ts +0 -24
  160. package/packages/ui/src/providers/WarqadProvider.tsx +0 -69
  161. package/packages/ui/src/styles.css +0 -26
  162. package/packages/ui/src/utils/cn.ts +0 -6
  163. package/packages/ui/src/utils/pdf.ts +0 -171
  164. package/packages/ui/tailwind.config.js +0 -13
  165. package/packages/ui/tsconfig.json +0 -17
  166. package/packages/ui/warqad-ui-0.0.1.tgz +0 -0
  167. package/packages/ui/warqadui-0.0.3.tgz +0 -0
  168. package/warqad-ui-0.0.1.tgz +0 -0
  169. /package/{packages/ui/dist → dist}/styles.d.mts +0 -0
  170. /package/{packages/ui/dist → dist}/styles.d.ts +0 -0
@@ -1,121 +0,0 @@
1
- import { forwardRef, useState } from "react";
2
- import { useWarqadConfig } from "../../providers/WarqadProvider";
3
- import {
4
- Controller,
5
- type FieldValues,
6
- type Path,
7
- type UseFormReturn,
8
- } from "react-hook-form";
9
-
10
- export interface TextareaProps<T extends FieldValues> extends Omit<
11
- React.TextareaHTMLAttributes<HTMLTextAreaElement>,
12
- "name" | "form"
13
- > {
14
- label: string;
15
- error?: string;
16
- containerClassName?: string;
17
- name?: Path<T>;
18
- form?: UseFormReturn<T>;
19
- }
20
-
21
- export const Textarea = forwardRef(
22
- <T extends FieldValues>(
23
- {
24
- label,
25
- error,
26
- containerClassName = "",
27
- name,
28
- form,
29
- onFocus,
30
- onBlur,
31
- className = "",
32
- ...props
33
- }: TextareaProps<T>,
34
- ref: React.ForwardedRef<HTMLTextAreaElement>,
35
- ) => {
36
- const [isFocused, setIsFocused] = useState(false);
37
- const { theme } = useWarqadConfig();
38
- const primaryColor = theme?.primaryColor;
39
-
40
- let message = error;
41
- if (form && name) {
42
- const {
43
- formState: { errors },
44
- } = form;
45
- const errorObj = name
46
- .split(".")
47
- .reduce((acc: any, current: string) => acc?.[current], errors);
48
- message = (errorObj as any)?.message;
49
- }
50
-
51
- const renderInput = (
52
- inputProps: any,
53
- ref: React.Ref<HTMLTextAreaElement> | undefined,
54
- ) => (
55
- <div className={`space-y-2 group ${containerClassName}`}>
56
- <label
57
- htmlFor={props.id}
58
- className={`block capitalize text-xs font-medium transition-colors duration-200`}
59
- style={{ color: isFocused ? primaryColor : undefined }}
60
- >
61
- {label}
62
- {props.required && <span className="text-red-500 ml-1">*</span>}
63
- </label>
64
- <div className="relative">
65
- <textarea
66
- ref={ref}
67
- onFocus={(e) => {
68
- setIsFocused(true);
69
- onFocus?.(e);
70
- }}
71
- onBlur={(e) => {
72
- setIsFocused(false);
73
- onBlur?.(e);
74
- }}
75
- className={`block w-full px-3 py-3 rounded-lg border-gray-200 dark:border-zinc-800 bg-gray-50 dark:bg-zinc-900/50 text-gray-900 dark:text-white placeholder-gray-400 focus:bg-white dark:focus:bg-zinc-900 outline-none transition-all duration-200 border min-h-[100px] resize-none text-sm ${className}`}
76
- style={{
77
- borderColor: isFocused ? primaryColor : undefined,
78
- boxShadow: isFocused
79
- ? `${primaryColor}33 0px 0px 0px 2px`
80
- : undefined,
81
- }}
82
- {...props}
83
- {...inputProps}
84
- />
85
- </div>
86
- {message && (
87
- <p className="text-sm text-red-600 dark:text-red-400">{message}</p>
88
- )}
89
- </div>
90
- );
91
-
92
- if (form && name) {
93
- return (
94
- <Controller
95
- control={form.control}
96
- name={name}
97
- render={({ field: { onChange, value, ref: fieldRef, onBlur } }) =>
98
- renderInput(
99
- {
100
- value: value || "", // Ensure controlled input doesn't warn about uncontrolled
101
- onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => {
102
- onChange(e);
103
- props.onChange?.(e);
104
- },
105
- onBlur: () => {
106
- onBlur();
107
- // props.onBlur?.(undefined as any);
108
- },
109
- },
110
- fieldRef,
111
- )
112
- }
113
- />
114
- );
115
- }
116
-
117
- return renderInput({}, ref);
118
- },
119
- ) as <T extends FieldValues>(
120
- props: TextareaProps<T> & { ref?: React.ForwardedRef<HTMLTextAreaElement> },
121
- ) => React.ReactElement;
@@ -1,11 +0,0 @@
1
- export const LoadingBox = () => {
2
- return (
3
- <div>
4
- <div className="flex items-center justify-center h-full">
5
- <div className="animate-spin rounded-full h-32 w-32 border-b-2 border-primary">
6
- aaa
7
- </div>
8
- </div>
9
- </div>
10
- );
11
- };
@@ -1,34 +0,0 @@
1
- import React from "react";
2
- import { cn } from "../utils/cn";
3
-
4
- interface PageHeaderProps {
5
- title: string;
6
- description?: string;
7
- children?: React.ReactNode;
8
- className?: string;
9
- }
10
-
11
- export const PageHeader = ({
12
- title,
13
- description,
14
- children,
15
- className,
16
- }: PageHeaderProps) => {
17
- return (
18
- <div className={cn("space-y-2 mb-8", className)}>
19
- <div className="flex items-center justify-between">
20
- <h1 className="text-3xl font-bold text-gray-900 dark:text-white tracking-tight">
21
- {title}
22
- </h1>
23
- {children}
24
- </div>
25
- {description && (
26
- <p className="text-gray-500 dark:text-gray-400 max-w-2xl leading-relaxed">
27
- {description}
28
- </p>
29
- )}
30
- </div>
31
- );
32
- };
33
-
34
- export default PageHeader;
@@ -1,35 +0,0 @@
1
- import React from "react";
2
- import { Sun, Moon } from "lucide-react";
3
- import { cn } from "../utils/cn";
4
- import { useTheme } from "../hooks/ThemeContext";
5
-
6
- export const ThemeToggle: React.FC<{ className?: string }> = ({
7
- className,
8
- }) => {
9
- const { isDarkMode, toggleTheme } = useTheme();
10
-
11
- return (
12
- <button
13
- onClick={toggleTheme}
14
- className={cn(
15
- "p-2 rounded-lg transition-all duration-200",
16
- "text-slate-500 hover:text-blue-600 hover:bg-slate-100",
17
- "dark:text-yellow-400 dark:hover:text-yellow-300 dark:hover:bg-slate-800",
18
- className,
19
- )}
20
- aria-label="Toggle dark mode"
21
- >
22
- {isDarkMode ? (
23
- <Sun
24
- size={20}
25
- className="stroke-2 transition-transform duration-300 rotate-0 scale-100"
26
- />
27
- ) : (
28
- <Moon
29
- size={20}
30
- className="stroke-2 transition-transform duration-300 rotate-0 scale-100"
31
- />
32
- )}
33
- </button>
34
- );
35
- };
@@ -1,81 +0,0 @@
1
- import React from "react";
2
- import { X } from "lucide-react";
3
- import { motion, AnimatePresence } from "framer-motion";
4
- import { ClassicSpin } from "../spins";
5
-
6
- export interface ModalProps {
7
- isOpen: boolean;
8
- onClose: () => void;
9
- title: string;
10
- children: React.ReactNode;
11
- isLoading?: boolean;
12
- width?: number;
13
- }
14
-
15
- export const Modal: React.FC<ModalProps> = ({
16
- isOpen,
17
- onClose,
18
- title,
19
- children,
20
- isLoading = false,
21
- width = 500,
22
- }) => {
23
- return (
24
- <AnimatePresence>
25
- {isOpen && (
26
- <div className="fixed inset-0 z-[1000] flex items-center justify-center p-4 sm:p-6">
27
- {/* Backdrop */}
28
- <motion.div
29
- initial={{ opacity: 0 }}
30
- animate={{ opacity: 1 }}
31
- exit={{ opacity: 0 }}
32
- onClick={isLoading ? undefined : onClose}
33
- className="fixed inset-0 bg-black/40 backdrop-blur-sm transition-all"
34
- />
35
-
36
- {/* Modal Content */}
37
- <motion.div
38
- initial={{ opacity: 0, scale: 0.95, y: 10 }}
39
- animate={{ opacity: 1, scale: 1, y: 0 }}
40
- exit={{ opacity: 0, scale: 0.95, y: 10 }}
41
- transition={{ type: "spring", duration: 0.3 }}
42
- style={{ maxWidth: width }}
43
- className="w-full bg-white dark:bg-zinc-900 rounded-[2rem] shadow-2xl border border-gray-200 dark:border-white/5 overflow-hidden relative z-10 flex flex-col max-h-[90vh]"
44
- >
45
- {/* Header */}
46
- <div className="px-8 py-5 border-b border-gray-100 dark:border-white/5 flex items-center justify-between bg-white/50 dark:bg-zinc-900/50 backdrop-blur-xl sticky top-0 z-20">
47
- <h3 className="text-xl font-bold text-gray-900 dark:text-white tracking-tight">
48
- {title}
49
- </h3>
50
- <button
51
- onClick={onClose}
52
- disabled={isLoading}
53
- className="p-2 -mr-2 rounded-full text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-white/5 transition-all disabled:opacity-50"
54
- >
55
- <X size={20} />
56
- </button>
57
- </div>
58
-
59
- {/* Glowing Top accent */}
60
- <div className="absolute top-0 left-0 right-0 h-1 bg-gradient-to-r from-blue-500 via-indigo-600 to-purple-500 opacity-60" />
61
-
62
- {/* Body */}
63
- <div className="p-8 overflow-y-auto relative flex-1">
64
- {/* Loading Overlay */}
65
- {isLoading && <ClassicSpin />}
66
- <div
67
- className={
68
- isLoading
69
- ? "opacity-20 blur-sm transition-all"
70
- : "transition-all"
71
- }
72
- >
73
- {children}
74
- </div>
75
- </div>
76
- </motion.div>
77
- </div>
78
- )}
79
- </AnimatePresence>
80
- );
81
- };
@@ -1,18 +0,0 @@
1
- import React from "react";
2
- import { Loader2 } from "lucide-react";
3
-
4
- export const ClassicSpin = ({ msg = "Please wait..." }: { msg?: string }) => {
5
- return (
6
- <div className="absolute inset-0 z-50 flex flex-col items-center justify-center bg-white/30 dark:bg-zinc-900/30 backdrop-blur-[0.5px] transition-all duration-200">
7
- <div className="flex flex-col items-center justify-center p-6 bg-white dark:bg-zinc-800 rounded-2xl shadow-2xl border border-gray-100 dark:border-zinc-700 animate-in zoom-in-95 duration-200">
8
- <div className="relative">
9
- <div className="absolute inset-0 bg-indigo-500 blur-lg opacity-20 animate-pulse"></div>
10
- <Loader2 className="h-8 w-8 animate-spin text-indigo-600 dark:text-indigo-400 relative z-10" />
11
- </div>
12
- <p className="mt-3 text-sm font-medium text-gray-900 dark:text-white">
13
- {msg}
14
- </p>
15
- </div>
16
- </div>
17
- );
18
- };
@@ -1,45 +0,0 @@
1
- import React from "react";
2
- import { cn } from "../../utils/cn";
3
-
4
- export interface LoadingSpinProps {
5
- className?: string;
6
- size?: "sm" | "md" | "lg";
7
- color?: string;
8
- }
9
-
10
- export const LoadingSpin = ({
11
- className,
12
- size = "md",
13
- color = "text-current",
14
- }: LoadingSpinProps) => {
15
- const sizeClasses = {
16
- sm: "h-4 w-4",
17
- md: "h-6 w-6",
18
- lg: "h-10 w-10",
19
- };
20
-
21
- return (
22
- <svg
23
- className={cn("animate-spin", sizeClasses[size], color, className)}
24
- fill="none"
25
- viewBox="0 0 24 24"
26
- xmlns="http://www.w3.org/2000/svg"
27
- >
28
- <circle
29
- className="opacity-25"
30
- cx="12"
31
- cy="12"
32
- r="10"
33
- stroke="currentColor"
34
- strokeWidth="4"
35
- />
36
- <path
37
- className="opacity-75"
38
- fill="currentColor"
39
- d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
40
- />
41
- </svg>
42
- );
43
- };
44
-
45
- export default LoadingSpin;
@@ -1,10 +0,0 @@
1
- export const OverlaySpin = ({ msg = "Processing..." }: { msg?: string }) => (
2
- <div className="absolute inset-0 bg-white/50 dark:bg-black/50 backdrop-blur-[1px] z-50 flex items-center justify-center rounded-xl transition-all duration-300">
3
- <div className="flex flex-col items-center gap-2 bg-white dark:bg-zinc-800 p-4 rounded-xl shadow-xl border border-gray-100 dark:border-zinc-700">
4
- <div className="w-6 h-6 border-2 border-blue-600 border-t-transparent rounded-full animate-spin"></div>
5
- <span className="text-xs font-medium text-gray-500 animate-pulse">
6
- {msg}
7
- </span>
8
- </div>
9
- </div>
10
- );
@@ -1,13 +0,0 @@
1
- import { ClassicSpin } from "./ClassicSpin";
2
- import { OverlaySpin } from "./OverlaySpin";
3
- import { LoadingSpin } from "./LoadingSpin";
4
-
5
- export { ClassicSpin, OverlaySpin, LoadingSpin };
6
-
7
- const Spins = {
8
- ClassicSpin,
9
- OverlaySpin,
10
- LoadingSpin,
11
- };
12
-
13
- export default Spins;
@@ -1,261 +0,0 @@
1
- import { useState, useMemo, useEffect } from "react";
2
- import {
3
- useReactTable,
4
- getCoreRowModel,
5
- getPaginationRowModel,
6
- getSortedRowModel,
7
- getFilteredRowModel,
8
- flexRender,
9
- type ColumnDef,
10
- type SortingState,
11
- type ColumnFiltersState,
12
- type VisibilityState,
13
- } from "@tanstack/react-table";
14
- import { ChevronDown, Search } from "lucide-react";
15
- import Fields from "../Fields";
16
- import { useWarqadConfig } from "../../providers/WarqadProvider";
17
-
18
- interface DataTableProps<TData, TValue> {
19
- columns: ColumnDef<TData, TValue>[];
20
- data: TData[];
21
- isLoading?: boolean;
22
- pageRows?: number;
23
- searchPlaceholder?: string;
24
- className?: string;
25
- onChange?: (state: {
26
- pagination: {
27
- pageIndex: number;
28
- pageSize: number;
29
- pageCount: number;
30
- };
31
- sorting: SortingState;
32
- columnFilters: ColumnFiltersState;
33
- globalFilter: string;
34
- selectedRows: TData[];
35
- filteredData: TData[];
36
- }) => void;
37
- }
38
-
39
- export function DataTable<TData, TValue>({
40
- columns,
41
- data,
42
- isLoading = false,
43
- pageRows,
44
- searchPlaceholder = "Search all columns...",
45
- className = "",
46
- onChange,
47
- }: DataTableProps<TData, TValue>) {
48
- const { theme } = useWarqadConfig();
49
- const primaryColor = theme?.primaryColor;
50
- const [sorting, setSorting] = useState<SortingState>([]);
51
- const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
52
- const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
53
- const [rowSelection, setRowSelection] = useState({});
54
- const [globalFilter, setGlobalFilter] = useState("");
55
-
56
- const table = useReactTable({
57
- data,
58
- columns,
59
- onSortingChange: setSorting,
60
- onColumnFiltersChange: setColumnFilters,
61
- getCoreRowModel: getCoreRowModel(),
62
- getPaginationRowModel: pageRows ? getPaginationRowModel() : undefined,
63
- getSortedRowModel: getSortedRowModel(),
64
- getFilteredRowModel: getFilteredRowModel(),
65
- onColumnVisibilityChange: setColumnVisibility,
66
- onRowSelectionChange: setRowSelection,
67
- onGlobalFilterChange: setGlobalFilter,
68
- globalFilterFn: "includesString",
69
- state: {
70
- sorting,
71
- columnFilters,
72
- columnVisibility,
73
- rowSelection,
74
- globalFilter,
75
- ...(pageRows ? { pagination: { pageSize: pageRows, pageIndex: 0 } } : {}),
76
- },
77
- manualPagination: false,
78
- });
79
-
80
- // Unified effect to handle all state changes
81
- useEffect(() => {
82
- if (onChange) {
83
- onChange({
84
- pagination: {
85
- pageIndex: table.getState().pagination.pageIndex,
86
- pageSize: table.getState().pagination.pageSize,
87
- pageCount: table.getPageCount(),
88
- },
89
- sorting,
90
- columnFilters,
91
- globalFilter,
92
- selectedRows: table
93
- .getSelectedRowModel()
94
- .rows.map((row) => row.original),
95
- filteredData: table
96
- .getFilteredRowModel()
97
- .rows.map((row) => row.original),
98
- });
99
- }
100
- }, [
101
- sorting,
102
- columnFilters,
103
- globalFilter,
104
- rowSelection,
105
- table,
106
- onChange,
107
- table.getState().pagination.pageIndex,
108
- table.getState().pagination.pageSize,
109
- ]);
110
-
111
- return (
112
- <div className={`space-y-4 w-full ${className}`}>
113
- {/* Search and Column Visibility Header */}
114
- <div className="flex items-center justify-between gap-4">
115
- <div className="flex-1 max-w-sm">
116
- <Fields.Input
117
- label="Search"
118
- placeholder={searchPlaceholder}
119
- value={globalFilter}
120
- onChange={(e: any) => setGlobalFilter(e.target.value)}
121
- icon={<Search size={16} />}
122
- className="!h-9"
123
- />
124
- </div>
125
-
126
- <div className="flex items-center gap-2">
127
- <div className="relative group">
128
- <button className="flex items-center gap-2 px-3 h-9 rounded-lg border border-gray-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 text-sm font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-zinc-800 transition-colors">
129
- Columns
130
- <ChevronDown size={14} className="text-gray-400" />
131
- </button>
132
-
133
- <div className="absolute right-0 top-full mt-2 w-48 py-1 bg-white dark:bg-zinc-900 border border-gray-200 dark:border-zinc-800 rounded-lg shadow-xl opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all z-50">
134
- {table
135
- .getAllColumns()
136
- .filter((column: any) => column.getCanHide())
137
- .map((column: any) => (
138
- <label
139
- key={column.id}
140
- className="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-zinc-800 cursor-pointer capitalize"
141
- >
142
- <input
143
- type="checkbox"
144
- checked={column.getIsVisible()}
145
- onChange={(e: any) =>
146
- column.toggleVisibility(!!e.target.checked)
147
- }
148
- className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
149
- style={{ accentColor: primaryColor }}
150
- />
151
- {column.id}
152
- </label>
153
- ))}
154
- </div>
155
- </div>
156
- </div>
157
- </div>
158
-
159
- {/* Table Container */}
160
- <div className="rounded-lg border border-gray-200 dark:border-zinc-800 bg-white dark:bg-zinc-950 overflow-hidden relative">
161
- <div className="overflow-x-auto">
162
- <table className="w-full text-left border-collapse">
163
- <thead className="bg-gray-50/50 dark:bg-zinc-900/50 border-b border-gray-200 dark:border-zinc-800">
164
- {table.getHeaderGroups().map((headerGroup: any) => (
165
- <tr key={headerGroup.id}>
166
- {headerGroup.headers.map((header: any) => (
167
- <th
168
- key={header.id}
169
- className="px-4 py-3 text-[13px] font-semibold text-gray-900 dark:text-zinc-100 text-left"
170
- >
171
- {header.isPlaceholder
172
- ? null
173
- : flexRender(
174
- header.column.columnDef.header,
175
- header.getContext(),
176
- )}
177
- </th>
178
- ))}
179
- </tr>
180
- ))}
181
- </thead>
182
- <tbody className="divide-y divide-gray-200 dark:divide-zinc-800">
183
- {isLoading ? (
184
- Array.from({ length: pageRows || 5 }).map((_, i) => (
185
- <tr
186
- key={`skeleton-${i}`}
187
- className="border-b border-gray-100 dark:border-zinc-800/50"
188
- >
189
- {columns.map((_, j) => (
190
- <td key={`skeleton-cell-${j}`} className="px-4 py-4">
191
- <div className="h-4 bg-gray-100 dark:bg-zinc-800 rounded animate-pulse w-full"></div>
192
- </td>
193
- ))}
194
- </tr>
195
- ))
196
- ) : table.getRowModel().rows?.length ? (
197
- table.getRowModel().rows.map((row: any) => (
198
- <tr
199
- key={row.id}
200
- className="hover:bg-gray-50/50 dark:hover:bg-zinc-900/50 transition-colors"
201
- data-state={row.getIsSelected() && "selected"}
202
- >
203
- {row.getVisibleCells().map((cell: any) => (
204
- <td
205
- key={cell.id}
206
- className="px-4 py-3 text-sm text-gray-700 dark:text-gray-200"
207
- >
208
- {flexRender(
209
- cell.column.columnDef.cell,
210
- cell.getContext(),
211
- )}
212
- </td>
213
- ))}
214
- </tr>
215
- ))
216
- ) : (
217
- <tr>
218
- <td
219
- colSpan={columns.length}
220
- className="h-32 text-center text-sm text-gray-500"
221
- >
222
- No results found.
223
- </td>
224
- </tr>
225
- )}
226
- </tbody>
227
- </table>
228
- </div>
229
- </div>
230
-
231
- {/* Footer / Pagination */}
232
- <div className="flex items-center justify-between px-2">
233
- <div className="flex-1 text-xs text-gray-500">
234
- {table.getFilteredSelectedRowModel().rows.length} of{" "}
235
- {table.getFilteredRowModel().rows.length} row(s) selected.
236
- </div>
237
-
238
- {pageRows && table.getPageCount() > 1 && (
239
- <div className="flex items-center gap-2">
240
- <button
241
- onClick={() => table.previousPage()}
242
- disabled={!table.getCanPreviousPage()}
243
- className="p-1 px-3 rounded-md border border-gray-200 dark:border-zinc-800 text-sm disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50 dark:hover:bg-zinc-800 transition-colors"
244
- >
245
- Previous
246
- </button>
247
- <button
248
- onClick={() => table.nextPage()}
249
- disabled={!table.getCanNextPage()}
250
- className="p-1 px-3 rounded-md border border-gray-200 dark:border-zinc-800 text-sm disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50 dark:hover:bg-zinc-800 transition-colors"
251
- >
252
- Next
253
- </button>
254
- </div>
255
- )}
256
- </div>
257
- </div>
258
- );
259
- }
260
-
261
- export default DataTable;
@@ -1 +0,0 @@
1
- export * from "./DataTable";