@adland/react 0.10.0 → 0.11.1
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/CHANGELOG.md
CHANGED
package/package.json
CHANGED
package/src/components/Ad.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect, useRef, useCallback } from "react";
|
|
2
2
|
import { sendTrackRequest } from "../utils/sdk";
|
|
3
3
|
import sdk from "@farcaster/miniapp-sdk";
|
|
4
|
-
import { Loader, SquareDashed } from "lucide-react";
|
|
4
|
+
import { FileWarningIcon, Loader, SquareDashed } from "lucide-react";
|
|
5
5
|
import { type AdData } from "@adland/data";
|
|
6
6
|
import { useFetch } from "../hooks/useFetch";
|
|
7
7
|
import BasicAdBody from "./BasicAdBody";
|
|
@@ -13,6 +13,7 @@ import FarcasterProfileAdContent from "./content/FarcasterProfileAdContent";
|
|
|
13
13
|
import { AdDataQueryError, AdProps } from "../types";
|
|
14
14
|
import { getBaseUrl } from "../utils";
|
|
15
15
|
import { adlandApiUrl } from "../utils/constants";
|
|
16
|
+
import { fetchAd } from "../fetch";
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Simple Ad component with built-in view and click tracking
|
|
@@ -39,36 +40,13 @@ export function Ad({
|
|
|
39
40
|
error,
|
|
40
41
|
} = useFetch<AdData>(
|
|
41
42
|
`ad-data-${owner}-${slotId}`,
|
|
42
|
-
|
|
43
|
-
const url = `${adlandApiUrl}/ad/owner/${owner.toLowerCase()}/slot/${slotId}`;
|
|
44
|
-
|
|
45
|
-
const res = await fetch(url, {
|
|
46
|
-
method: "GET",
|
|
47
|
-
headers: {
|
|
48
|
-
"Content-Type": "application/json",
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
if (!res.ok) {
|
|
53
|
-
throw new Error(AdDataQueryError.ERROR);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const data = await res.json();
|
|
57
|
-
|
|
58
|
-
if (data.error) {
|
|
59
|
-
throw new Error(data.error);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return data;
|
|
63
|
-
},
|
|
43
|
+
() => fetchAd(owner, slotId),
|
|
64
44
|
{
|
|
65
45
|
enabled: !!owner && !!slotId,
|
|
66
46
|
},
|
|
67
47
|
);
|
|
68
48
|
const networkBaseUrl = baseUrl ?? getBaseUrl(network);
|
|
69
49
|
|
|
70
|
-
console.log({ error, adData });
|
|
71
|
-
|
|
72
50
|
const send = useCallback(
|
|
73
51
|
(type: "view" | "click") => {
|
|
74
52
|
const trackEndpoint = `${networkBaseUrl}/api/analytics/track`;
|
|
@@ -187,7 +165,7 @@ function ErrorAdContent({ error }: { error: unknown }) {
|
|
|
187
165
|
return (
|
|
188
166
|
<BasicAdBody>
|
|
189
167
|
<div className="flex flex-row items-center gap-2">
|
|
190
|
-
<
|
|
168
|
+
<FileWarningIcon className="w-5 h-5 md:w-7 md:h-7" />
|
|
191
169
|
<p className="font-bold text-primary">ERROR</p>
|
|
192
170
|
</div>
|
|
193
171
|
</BasicAdBody>
|
|
@@ -216,7 +194,12 @@ function EmtpyAdContent({ data }: { data: { url: string } }) {
|
|
|
216
194
|
>
|
|
217
195
|
<div className="flex flex-row items-center gap-2">
|
|
218
196
|
<SquareDashed className="w-5 h-5 md:w-7 md:h-7" />
|
|
219
|
-
<p className="font-bold text-primary">
|
|
197
|
+
<p className="font-bold text-primary">
|
|
198
|
+
NO AD{" "}
|
|
199
|
+
<span className="text-xs text-muted-foreground/80 font-normal">
|
|
200
|
+
(Your ad here)
|
|
201
|
+
</span>
|
|
202
|
+
</p>
|
|
220
203
|
</div>
|
|
221
204
|
</BasicAdBody>
|
|
222
205
|
);
|
|
@@ -36,7 +36,7 @@ const FarcasterProfileAdContent = ({ data }: { data: FarcasterProfileAd }) => {
|
|
|
36
36
|
<div className="flex flex-row items-center gap-1">
|
|
37
37
|
{profileMetadata?.username ? (
|
|
38
38
|
<p className="text-sm font-bold text-primary truncate">
|
|
39
|
-
{profileMetadata.username}
|
|
39
|
+
@{profileMetadata.username}
|
|
40
40
|
</p>
|
|
41
41
|
) : (
|
|
42
42
|
<p className="text-sm font-bold text-primary">FID: {fid}</p>
|
|
@@ -3,33 +3,10 @@ import sdk from "@farcaster/miniapp-sdk";
|
|
|
3
3
|
import BasicAdBody from "../BasicAdBody";
|
|
4
4
|
import { adCardIcon } from "../../utils/constants";
|
|
5
5
|
|
|
6
|
-
// Token Ad Component
|
|
7
6
|
const TokenAdContent = ({ data }: { data: TokenAd }) => {
|
|
8
7
|
const Icon = adCardIcon["token"];
|
|
9
8
|
const { data: tokenData, metadata: tokenMetadata } = data;
|
|
10
9
|
|
|
11
|
-
// Build block explorer URL based on chainId
|
|
12
|
-
const getTokenUrl = () => {
|
|
13
|
-
const address = tokenData.address;
|
|
14
|
-
const chainId = tokenData.chainId;
|
|
15
|
-
|
|
16
|
-
// Common block explorers by chainId
|
|
17
|
-
const explorers: Record<number, string> = {
|
|
18
|
-
1: "https://etherscan.io/token/",
|
|
19
|
-
8453: "https://basescan.org/token/",
|
|
20
|
-
42161: "https://arbiscan.io/token/",
|
|
21
|
-
10: "https://optimistic.etherscan.io/token/",
|
|
22
|
-
137: "https://polygonscan.com/token/",
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const baseUrl = explorers[chainId];
|
|
26
|
-
if (baseUrl) {
|
|
27
|
-
return `${baseUrl}${address}`;
|
|
28
|
-
}
|
|
29
|
-
// Fallback to Etherscan if chain not recognized
|
|
30
|
-
return `https://etherscan.io/token/${address}`;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
10
|
return (
|
|
34
11
|
<BasicAdBody
|
|
35
12
|
name={"TOKEN"}
|
|
@@ -56,7 +33,7 @@ const TokenAdContent = ({ data }: { data: TokenAd }) => {
|
|
|
56
33
|
)}
|
|
57
34
|
{tokenMetadata?.symbol ? (
|
|
58
35
|
<p className="text-sm font-bold text-primary truncate">
|
|
59
|
-
{tokenMetadata.symbol.toUpperCase()}
|
|
36
|
+
${tokenMetadata.symbol.toUpperCase()}
|
|
60
37
|
</p>
|
|
61
38
|
) : (
|
|
62
39
|
<p className="text-sm font-bold text-primary">TOKEN</p>
|
package/src/fetch.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { AdDataQueryError } from "./types";
|
|
2
|
+
import { adlandApiUrl } from "./utils/constants";
|
|
3
|
+
|
|
4
|
+
export const fetchAd = async (owner: string, slotId: string) => {
|
|
5
|
+
const url = `${adlandApiUrl}/ad/owner/${owner.toLowerCase()}/slot/${slotId}`;
|
|
6
|
+
|
|
7
|
+
const res = await fetch(url, {
|
|
8
|
+
method: "GET",
|
|
9
|
+
headers: {
|
|
10
|
+
"Content-Type": "application/json",
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
if (!res.ok) {
|
|
15
|
+
if (res.status === 404) {
|
|
16
|
+
throw new Error(AdDataQueryError.NO_AD);
|
|
17
|
+
}
|
|
18
|
+
throw new Error(AdDataQueryError.ERROR);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const data = await res.json();
|
|
22
|
+
|
|
23
|
+
if (data.error) {
|
|
24
|
+
throw new Error(data.error);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return data;
|
|
28
|
+
};
|