@hobenakicoffee/libraries 3.4.2 → 4.1.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.
- package/LICENSE +21 -0
- package/README.md +119 -246
- package/package.json +25 -22
- package/src/App.tsx +194 -19
- package/src/index.css +0 -1
- package/src/types/supabase.ts +940 -3
- package/src/components/turnstile-captcha.tsx +0 -47
- package/src/components/ui/button.tsx +0 -77
- package/src/components/ui/calendar.tsx +0 -235
- package/src/components/ui/spinner.tsx +0 -18
- package/src/constants/common.test.ts +0 -33
- package/src/constants/legal.test.ts +0 -72
- package/src/constants/payment.test.ts +0 -259
- package/src/constants/platforms.test.ts +0 -66
- package/src/constants/services.test.ts +0 -58
- package/src/lib/utils.ts +0 -6
- package/src/moderation/profanity-service.test.ts +0 -106
- package/src/providers/theme-provider.tsx +0 -73
- package/src/utils/check-moderation.test.ts +0 -321
- package/src/utils/format-amount.test.ts +0 -30
- package/src/utils/format-count.test.ts +0 -56
- package/src/utils/format-date.test.ts +0 -19
- package/src/utils/format-number.test.ts +0 -29
- package/src/utils/format-plain-text.test.ts +0 -36
- package/src/utils/get-newsletter-post-link.test.ts +0 -27
- package/src/utils/get-product-link.test.ts +0 -34
- package/src/utils/get-social-handle.test.ts +0 -32
- package/src/utils/get-social-link.test.ts +0 -63
- package/src/utils/get-user-name-initials.test.ts +0 -34
- package/src/utils/get-user-page-link.test.ts +0 -9
- package/src/utils/open-to-new-window.test.ts +0 -34
- package/src/utils/post-to-facebook.test.ts +0 -43
- package/src/utils/post-to-instagram.test.ts +0 -56
- package/src/utils/post-to-linkedin.test.ts +0 -43
- package/src/utils/post-to-x.test.ts +0 -45
- package/src/utils/qr-svg-utils.test.ts +0 -104
- package/src/utils/to-human-readable.test.ts +0 -25
- package/src/utils/validate-phone-number.test.ts +0 -28
package/src/App.tsx
CHANGED
|
@@ -1,28 +1,203 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { productInfo } from "@/constants/legal";
|
|
3
|
+
|
|
4
|
+
declare const __LATEST_VERSION__: string;
|
|
5
|
+
|
|
6
|
+
const EXPORTS = [
|
|
7
|
+
{
|
|
8
|
+
path: "/constants",
|
|
9
|
+
name: "constants",
|
|
10
|
+
desc: "Payment, Platform, Visibility consts",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
path: "/utils",
|
|
14
|
+
name: "utils",
|
|
15
|
+
desc: "Formatters, validators, social helpers",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
path: "/types",
|
|
19
|
+
name: "types",
|
|
20
|
+
desc: "Supabase + custom TypeScript types",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
path: "/moderation",
|
|
24
|
+
name: "moderation",
|
|
25
|
+
desc: "Profanity detection EN/BN",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
path: "/nuqs",
|
|
29
|
+
name: "nuqs",
|
|
30
|
+
desc: "URL state parsers (zod)",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
path: "/scripts",
|
|
34
|
+
name: "scripts",
|
|
35
|
+
desc: "Build utilities",
|
|
36
|
+
},
|
|
37
|
+
{ path: "/hooks", name: "hooks", desc: "React hooks" },
|
|
38
|
+
{ path: "/docs", name: "docs", desc: "Documentation & guides" },
|
|
39
|
+
];
|
|
5
40
|
|
|
6
41
|
const App = () => {
|
|
7
|
-
const [
|
|
42
|
+
const [copied, setCopied] = useState(false);
|
|
43
|
+
|
|
44
|
+
const handleCopy = () => {
|
|
45
|
+
navigator.clipboard.writeText("bun add @hobenakicoffee/libraries");
|
|
46
|
+
setCopied(true);
|
|
47
|
+
setTimeout(() => setCopied(false), 2000);
|
|
48
|
+
};
|
|
8
49
|
|
|
9
50
|
return (
|
|
10
|
-
<div className="
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<Button>Click me</Button>
|
|
16
|
-
|
|
17
|
-
<Calendar
|
|
18
|
-
captionLayout="dropdown"
|
|
19
|
-
className="rounded-lg border"
|
|
20
|
-
mode="single"
|
|
21
|
-
onSelect={setDate}
|
|
22
|
-
selected={date}
|
|
23
|
-
/>
|
|
24
|
-
{getProductLink("leo", "example-product-slug")}
|
|
51
|
+
<div className="min-dvh relative flex flex-col overflow-hidden bg-[#0a0c10] text-slate-200">
|
|
52
|
+
<div className="pointer-events-none absolute inset-0 overflow-hidden">
|
|
53
|
+
<div className="absolute inset-0 bg-[linear-gradient(to_right,#1e293b_0.5px,transparent_0.5px),linear-gradient(to_bottom,#1e293b_0.5px,transparent_0.5px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_60%_50%_at_50%_50%,#000_70%,transparent_100%)]" />
|
|
54
|
+
<div className="absolute top-0 left-1/4 h-[500px] w-[500px] -translate-x-1/2 rounded-full bg-indigo-500/[0.03] blur-3xl" />
|
|
55
|
+
<div className="absolute right-1/4 bottom-0 h-[400px] w-[400px] translate-y-1/2 rounded-full bg-cyan-500/[0.03] blur-3xl" />
|
|
25
56
|
</div>
|
|
57
|
+
|
|
58
|
+
<header className="relative z-10 flex items-center justify-between px-6 py-4 md:px-8">
|
|
59
|
+
<div className="flex items-center gap-3">
|
|
60
|
+
<div className="flex h-10 w-10 items-center justify-center rounded-lg border border-slate-700 bg-slate-900 shadow-[0_0_20px_rgba(99,102,241,0.2)]">
|
|
61
|
+
<span className="font-bold font-mono text-cyan-400 text-lg">H</span>
|
|
62
|
+
</div>
|
|
63
|
+
<div>
|
|
64
|
+
<h1 className="font-mono font-semibold text-slate-100 text-sm tracking-tight">
|
|
65
|
+
@hobenakicoffee/libraries
|
|
66
|
+
</h1>
|
|
67
|
+
<p className="font-mono text-slate-500 text-xs">
|
|
68
|
+
{__LATEST_VERSION__}
|
|
69
|
+
</p>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
<div className="flex items-center gap-2 rounded-md border border-slate-800 bg-slate-900/50 px-2 py-1 font-mono text-slate-400 text-xs">
|
|
73
|
+
<span className="h-2 w-2 rounded-full bg-green-500" />
|
|
74
|
+
TypeScript
|
|
75
|
+
</div>
|
|
76
|
+
</header>
|
|
77
|
+
|
|
78
|
+
<main className="relative z-10 flex flex-1 flex-col items-center justify-center px-4 py-12 md:px-6">
|
|
79
|
+
<div className="mx-auto max-w-2xl text-center">
|
|
80
|
+
<div className="mb-6 inline-flex items-center gap-2 rounded-md border border-slate-800 bg-slate-900/30 px-3 py-1 font-mono text-slate-400 text-xs">
|
|
81
|
+
<span>framework-agnostic</span>
|
|
82
|
+
<span className="text-slate-600">{"//"}</span>
|
|
83
|
+
<span>tree-shakeable</span>
|
|
84
|
+
<span className="text-slate-600">{"//"}</span>
|
|
85
|
+
<span>zod-powered</span>
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<h2 className="mb-4 font-bold font-mono text-3xl tracking-tight md:text-5xl">
|
|
89
|
+
<span className="text-slate-100">Shared </span>
|
|
90
|
+
<span className="bg-linear-to-r from-cyan-400 to-indigo-400 bg-clip-text text-transparent">
|
|
91
|
+
constants,
|
|
92
|
+
</span>
|
|
93
|
+
<br />
|
|
94
|
+
<span className="text-slate-100">utilities & </span>
|
|
95
|
+
<span className="bg-linear-to-r from-cyan-400 to-indigo-400 bg-clip-text text-transparent">
|
|
96
|
+
types
|
|
97
|
+
</span>
|
|
98
|
+
</h2>
|
|
99
|
+
|
|
100
|
+
<p className="mx-auto mb-8 max-w-lg font-mono text-slate-400 text-sm leading-relaxed">
|
|
101
|
+
The core package for{" "}
|
|
102
|
+
<span className="text-cyan-400">"{productInfo.name}"</span>{" "}
|
|
103
|
+
projects. Build faster with pre-built constants, utilities, types,
|
|
104
|
+
and moderation tools.
|
|
105
|
+
</p>
|
|
106
|
+
|
|
107
|
+
<div className="group relative mx-auto inline-flex cursor-pointer flex-col items-center gap-3 md:flex-row">
|
|
108
|
+
<div className="flex items-center gap-2 rounded-lg border border-slate-700 bg-slate-900 p-1 pr-3 font-mono text-sm shadow-[0_0_40px_rgba(99,102,241,0.15)] transition-all group-hover:border-cyan-500/50 group-hover:shadow-[0_0_60px_rgba(99,102,241,0.25)]">
|
|
109
|
+
<button
|
|
110
|
+
className="flex items-center gap-2 rounded-md bg-slate-800 px-3 py-2 text-slate-200 transition-colors hover:bg-slate-700"
|
|
111
|
+
onClick={handleCopy}
|
|
112
|
+
type="button"
|
|
113
|
+
>
|
|
114
|
+
<span className="text-cyan-400">$</span>
|
|
115
|
+
<span>
|
|
116
|
+
{copied ? " Copied!" : " bun add @hobenakicoffee/libraries"}
|
|
117
|
+
</span>
|
|
118
|
+
</button>
|
|
119
|
+
<span className="text-slate-500">{copied ? "✓" : "›"}</span>
|
|
120
|
+
</div>
|
|
121
|
+
<a
|
|
122
|
+
className="inline-flex items-center gap-2 rounded-lg bg-indigo-600 px-4 py-3 font-mono text-sm text-white transition-all hover:bg-indigo-600/90"
|
|
123
|
+
href="/docs/"
|
|
124
|
+
>
|
|
125
|
+
<span>Documentation</span>
|
|
126
|
+
<span className="text-indigo-500">→</span>
|
|
127
|
+
</a>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<div className="mt-16 w-full max-w-4xl">
|
|
132
|
+
<div className="mb-3 font-mono text-slate-500 text-xs">
|
|
133
|
+
{"// exports"}
|
|
134
|
+
</div>
|
|
135
|
+
<div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-3">
|
|
136
|
+
{EXPORTS.map((exp, i) => (
|
|
137
|
+
<a
|
|
138
|
+
className="group relative overflow-hidden rounded-lg border border-slate-800 bg-slate-900/50 p-3 font-mono transition-all hover:border-slate-600"
|
|
139
|
+
href={
|
|
140
|
+
exp.path === "/docs" ? exp.path : `/docs${exp.path}/overview`
|
|
141
|
+
}
|
|
142
|
+
key={exp.path}
|
|
143
|
+
style={{ animationDelay: `${i * 50}ms` }}
|
|
144
|
+
>
|
|
145
|
+
<div className="absolute inset-0 bg-linear-to-r from-cyan-500/0 to-indigo-500/0 opacity-0 transition-opacity group-hover:from-cyan-500/[0.03] group-hover:to-indigo-500/[0.03] group-hover:opacity-100" />
|
|
146
|
+
<div className="relative">
|
|
147
|
+
<span className="text-cyan-400 text-xs">
|
|
148
|
+
@hobenakicoffee/libraries
|
|
149
|
+
</span>
|
|
150
|
+
<span className="text-slate-500 text-xs">{exp.path}</span>
|
|
151
|
+
</div>
|
|
152
|
+
<div className="relative mt-1 text-slate-500 text-xs">
|
|
153
|
+
{exp.desc}
|
|
154
|
+
</div>
|
|
155
|
+
</a>
|
|
156
|
+
))}
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
|
|
160
|
+
<div className="mt-12 w-full max-w-2xl overflow-x-auto rounded-lg border border-slate-800 bg-slate-950 p-4 font-mono text-xs">
|
|
161
|
+
<div className="tems-center mb-2 gap-2 text-slate-500">
|
|
162
|
+
<span className="h-3 w-3 rounded-full bg-emerald-500/20" />
|
|
163
|
+
main.ts
|
|
164
|
+
</div>
|
|
165
|
+
<pre className="text-slate-300">
|
|
166
|
+
<code>
|
|
167
|
+
<span className="text-purple-400">import</span> {"{"}{" "}
|
|
168
|
+
<span className="text-cyan-400">PaymentStatuses</span>, {""}
|
|
169
|
+
<span className="text-cyan-400">SupporterPlatforms</span>
|
|
170
|
+
{"}"} <span className="text-purple-400">from</span>{" "}
|
|
171
|
+
<span className="text-amber-300">
|
|
172
|
+
"@hobenakicoffee/libraries"
|
|
173
|
+
</span>
|
|
174
|
+
{"\n"}
|
|
175
|
+
<span className="text-purple-400">import</span> {"{"}{" "}
|
|
176
|
+
<span className="text-cyan-400">formatAmount</span>, {""}
|
|
177
|
+
<span className="text-cyan-400">getUserPageLink</span>
|
|
178
|
+
{"}"} <span className="text-purple-400">from</span>{" "}
|
|
179
|
+
<span className="text-amber-300">
|
|
180
|
+
"@hobenakicoffee/libraries/utils"
|
|
181
|
+
</span>
|
|
182
|
+
{"\n"}
|
|
183
|
+
<span className="text-purple-400">import</span> type {"{"}{" "}
|
|
184
|
+
<span className="text-cyan-400">Database</span>
|
|
185
|
+
{"}"} <span className="text-purple-400">from</span>{" "}
|
|
186
|
+
<span className="text-amber-300">
|
|
187
|
+
"@hobenakicoffee/libraries/types"
|
|
188
|
+
</span>
|
|
189
|
+
</code>
|
|
190
|
+
</pre>
|
|
191
|
+
</div>
|
|
192
|
+
</main>
|
|
193
|
+
|
|
194
|
+
<footer className="relative z-10 px-6 py-4 text-center">
|
|
195
|
+
<p className="font-mono text-slate-600 text-xs">
|
|
196
|
+
<span>© {new Date().getFullYear()}</span>
|
|
197
|
+
<span className="text-slate-700">{" // "}</span>
|
|
198
|
+
<span className="text-slate-500">{productInfo.name}</span>
|
|
199
|
+
</p>
|
|
200
|
+
</footer>
|
|
26
201
|
</div>
|
|
27
202
|
);
|
|
28
203
|
};
|