Skip to content

Commit f83b27f

Browse files
committed
siwa updates and new article
1 parent e8a25d7 commit f83b27f

File tree

7 files changed

+121
-16
lines changed

7 files changed

+121
-16
lines changed

apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ function CustomChatContentLoggedIn(props: {
102102
message:
103103
messageToSend.content.find((x) => x.type === "text")?.text ?? "",
104104
conversationId: sessionId,
105+
source: "dashboard-support",
105106
};
106107
const apiUrl = process.env.NEXT_PUBLIC_SIWA_URL;
107108
const response = await fetch(`${apiUrl}/v1/chat`, {

apps/portal/src/app/knowledge-base/sidebar.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ export const sidebar: SideBar = {
7070
name: "Batch Upload",
7171
href: "/knowledge-base/troubleshoot/contracts/batch-upload",
7272
},
73+
{
74+
name: "Transfer Amount Exceeds Allowance",
75+
href: "/knowledge-base/troubleshoot/contracts/erc20-transfer-allowance"
76+
}
7377
],
7478
},
7579
],
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# ERC20 - Transfer Amount Exceeds Allowance
2+
3+
## What it means
4+
5+
The "ERC20: transfer amount exceeds allowance" error occurs when trying to transfer ERC20 tokens beyond the allowed limit set by the token owner. ERC20 tokens use an allowance system that grants specific addresses permission to transfer a certain amount of tokens on behalf of the owner.
6+
7+
## How to fix it
8+
9+
1. Check allowance: Use the thirdweb Dashboard to verify the current allowance for the sender’s address.
10+
2. Increase allowance: If the allowance is too low, the token owner should call the approve function to increase it.
11+
3. Transfer tokens: Once the allowance is updated, retry the transfer using transferFrom or transfer.
12+
13+
Following these steps should resolve the error. Ensure the allowance covers the transfer amount before initiating.
14+
15+
Can't get this working? [**Contact our support team**](https://thirdweb.com/support) for help.

apps/portal/src/app/page.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import { PlaygroundIcon } from "../icons/products/PlaygroundIcon";
1515
import { cn } from "../lib/utils";
1616
import DocsHeroDark from "./_images/docs-hero-dark.png";
1717
import DocsHeroLight from "./_images/docs-hero-light.png";
18+
import { Button } from "@/components/ui/button";
19+
import { MessageCircleIcon } from "lucide-react";
1820
export default function Page() {
1921
return (
2022
<main className="container max-w-[900px] grow pb-20" data-noindex>
@@ -40,6 +42,13 @@ function Hero() {
4042
<p className="mb-8 max-w-md text-lg text-muted-foreground leading-normal">
4143
Development framework for building onchain apps, games, and agents.
4244
</p>
45+
46+
<Link href="/chat">
47+
<Button className="flex items-center gap-2">
48+
<MessageCircleIcon className="size-4" />
49+
Ask AI Assistant
50+
</Button>
51+
</Link>
4352
</div>
4453
</div>
4554

@@ -227,4 +236,4 @@ function ArticleCardIndex(props: {
227236
</div>
228237
</Link>
229238
);
230-
}
239+
}

apps/portal/src/components/AI/api.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const getChatResponse = async (
1111
const payload = {
1212
message: userMessage,
1313
conversationId: sessionId,
14+
source: "portal",
1415
};
1516
const response = await fetch(`${apiUrl}/v1/chat`, {
1617
method: "POST",
@@ -41,3 +42,33 @@ export const getChatResponse = async (
4142
return null;
4243
}
4344
};
45+
46+
export const sendFeedback = async (
47+
conversationId: string,
48+
feedbackRating: 1 | -1,
49+
) => {
50+
try {
51+
const response = await fetch(`${apiUrl}/v1/chat/feedback`, {
52+
method: "POST",
53+
headers: {
54+
"Content-Type": "application/json",
55+
"x-service-api-key": serviceKey,
56+
},
57+
body: JSON.stringify({ conversationId, feedbackRating }),
58+
});
59+
60+
if (!response.ok) {
61+
const error = await response.text();
62+
throw new Error(
63+
`Failed to send feedback: ${response.status} - ${error}`,
64+
);
65+
}
66+
return true;
67+
} catch (error) {
68+
console.error(
69+
"Feedback API error:",
70+
error instanceof Error ? error.message : "Unknown error",
71+
);
72+
return false;
73+
}
74+
};

apps/portal/src/components/AI/chat.tsx

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { LoadingDots } from "@/components/ui/LoadingDots";
55
import { Button } from "@/components/ui/button";
66
import { AutoResizeTextarea } from "@/components/ui/textarea";
77
import { cn } from "@/lib/utils";
8-
import { ArrowUpIcon, BotIcon } from "lucide-react";
8+
import { ArrowUpIcon, ThumbsUpIcon, ThumbsDownIcon } from "lucide-react";
99
import { usePostHog } from "posthog-js/react";
1010
import {
1111
type ChangeEvent,
@@ -15,13 +15,15 @@ import {
1515
useRef,
1616
useState,
1717
} from "react";
18-
import { getChatResponse } from "./api";
18+
import { getChatResponse, sendFeedback } from "./api";
19+
import siwaIcon from "@/icons/siwa-icon.png";
1920

2021
interface Message {
2122
id: string;
2223
role: "user" | "assistant";
2324
content: string;
2425
isLoading?: boolean;
26+
feedback?: 1 | -1;
2527
}
2628

2729
const predefinedPrompts = [
@@ -36,7 +38,7 @@ function ChatEmptyState({
3638
}: { onPromptClick: (prompt: string) => void }) {
3739
return (
3840
<div className="flex flex-col items-center justify-center space-y-8 py-16 text-center">
39-
<BotIcon className="size-16" />
41+
<img src={siwaIcon.src} alt="SIWA" className="size-16" />
4042

4143
<h2 className="font-semibold text-3xl text-foreground">
4244
How can I help you <br />
@@ -132,13 +134,17 @@ export function Chat() {
132134
);
133135

134136
useEffect(() => {
135-
if (lastMessageRef.current && messages.length > 0) {
136-
lastMessageRef.current.scrollIntoView({
137-
behavior: "smooth",
138-
block: "start",
139-
});
140-
}
141-
}, [messages.length]);
137+
const timer = setTimeout(() => {
138+
if (lastMessageRef.current) {
139+
lastMessageRef.current.scrollIntoView({
140+
behavior: "smooth",
141+
block: "end",
142+
});
143+
}
144+
}, 100);
145+
146+
return () => clearTimeout(timer);
147+
}, [messages]);
142148

143149
const handleInputChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
144150
setInput(e.target.value);
@@ -153,6 +159,21 @@ export function Chat() {
153159
}
154160
};
155161

162+
const handleFeedback = async (messageId: string, feedback: 1 | -1) => {
163+
if (!conversationId) return; // Don't send feedback if no conversation
164+
165+
try {
166+
await sendFeedback(conversationId, feedback);
167+
setMessages((prevMessages) =>
168+
prevMessages.map((msg) =>
169+
msg.id === messageId ? { ...msg, feedback } : msg
170+
)
171+
);
172+
} catch (e) {
173+
// Optionally handle error
174+
}
175+
};
176+
156177
return (
157178
<div
158179
className="mx-auto flex size-full flex-col overflow-hidden lg:min-w-[800px] lg:max-w-5xl"
@@ -183,11 +204,35 @@ export function Chat() {
183204
{message.role === "assistant" && message.isLoading ? (
184205
<LoadingDots />
185206
) : (
186-
<StyledMarkdownRenderer
187-
text={message.content}
188-
isMessagePending={false}
189-
type={message.role}
190-
/>
207+
<>
208+
<StyledMarkdownRenderer
209+
text={message.content}
210+
isMessagePending={false}
211+
type={message.role}
212+
/>
213+
{message.role === "assistant" && !message.isLoading && (
214+
<div className="flex gap-2 mt-2">
215+
{!message.feedback && (
216+
<>
217+
<button
218+
aria-label="Thumbs up"
219+
className="hover:text-green-500 transition-colors text-muted-foreground"
220+
onClick={() => handleFeedback(message.id, 1)}
221+
>
222+
<ThumbsUpIcon className="size-5" />
223+
</button>
224+
<button
225+
aria-label="Thumbs down"
226+
className="hover:text-red-500 transition-colors text-muted-foreground"
227+
onClick={() => handleFeedback(message.id, -1)}
228+
>
229+
<ThumbsDownIcon className="size-5" />
230+
</button>
231+
</>
232+
)}
233+
</div>
234+
)}
235+
</>
191236
)}
192237
</div>
193238
</div>

apps/portal/src/icons/siwa-icon.png

1.29 KB
Loading

0 commit comments

Comments
 (0)