Skip to content

Commit ee1fa56

Browse files
committed
fix: toast refine & replace to hash router & some fix
1 parent 145d28c commit ee1fa56

18 files changed

+179
-73
lines changed

.env

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VITE_BASE_URL=https://knowledge.rentsoft.cn
1+
# VITE_BASE_URL=https://smart-qa-service.com

src/api/index.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import createAxiosInstance from "@/utils/request";
22
import { CancelToken } from "axios";
33

4-
const request = createAxiosInstance(import.meta.env.VITE_BASE_URL);
4+
const hostname = window.location.hostname;
5+
const protocol = window.location.protocol;
6+
const isHttps = protocol === "https:";
7+
8+
const guessUrl = `${protocol}//${hostname}${isHttps ? "" : ":7000"}`;
9+
10+
const request = createAxiosInstance(import.meta.env.VITE_BASE_URL || guessUrl);
511

612
export const adminLogin = (
713
account_name: string,

src/components/ui/calendar.tsx

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import * as React from "react"
2-
import { ChevronLeft, ChevronRight } from "lucide-react"
3-
import { DayPicker } from "react-day-picker"
1+
import * as React from "react";
2+
import { ChevronLeft, ChevronRight } from "lucide-react";
3+
import { DayPicker } from "react-day-picker";
44

5-
import { cn } from "@/lib/utils"
6-
import { buttonVariants } from "@/components/ui/button"
5+
import { cn } from "@/lib/utils";
6+
import { buttonVariants } from "@/components/ui/button";
77

8-
export type CalendarProps = React.ComponentProps<typeof DayPicker>
8+
export type CalendarProps = React.ComponentProps<typeof DayPicker>;
99

1010
function Calendar({
1111
className,
@@ -52,13 +52,13 @@ function Calendar({
5252
...classNames,
5353
}}
5454
components={{
55-
IconLeft: ({ ...props }) => <ChevronLeft className="h-4 w-4" />,
56-
IconRight: ({ ...props }) => <ChevronRight className="h-4 w-4" />,
55+
IconLeft: () => <ChevronLeft className="h-4 w-4" />,
56+
IconRight: () => <ChevronRight className="h-4 w-4" />,
5757
}}
5858
{...props}
5959
/>
60-
)
60+
);
6161
}
62-
Calendar.displayName = "Calendar"
62+
Calendar.displayName = "Calendar";
6363

64-
export { Calendar }
64+
export { Calendar };

src/components/ui/field.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import {
88
SelectValue,
99
} from "@/components/ui/select";
1010

11-
interface FieldProps {}
12-
1311
const Field = () => {
1412
return (
1513
<>

src/layout/ChangePasswordDialog.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export function ChangePasswordDialog({
4949
removeToken();
5050
router.navigate("/login");
5151
} catch (error) {
52-
toast.error("Failed to update password.");
52+
toast.error((error as any).message || "Failed to update password.");
5353
}
5454
setLoading(false);
5555
};

src/layout/LogoutAlert.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const LogoutAlert = ({
2020
}) => {
2121
const confirmLogout = () => {
2222
removeToken();
23-
router.navigate("/login");
23+
router.navigate(`/login`);
2424
};
2525

2626
return (

src/pages/Embed.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@ import { useState } from "react";
55
const hostname = window.location.hostname;
66

77
const iframe = `<iframe
8-
src="https://${hostname}/chatbot-iframe"
8+
src="https://${hostname}/open-kf-chatbot"
99
title="Chatbot"
1010
style="min-width: 420px;min-height: 60vh"
1111
frameborder="0"
1212
></iframe>`;
1313

14-
const script = `<script src="https://${hostname}/embed.min.js" defer></script>`;
14+
const script = `<script
15+
src="https://${hostname}/open-kf-chatbot/embed.js"
16+
bot-domain="https://${hostname}/open-kf-chatbot"
17+
defer
18+
></script>`;
1519

1620
export const Embed = () => {
1721
const [copied, setCopied] = useState({

src/pages/Login.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export function Login() {
3939
saveToken(token);
4040
router.navigate("/");
4141
} catch (error) {
42-
toast.error("Failed to login.");
42+
toast.error((error as any).message || "Failed to login.");
4343
}
4444
setLoading(false);
4545
};

src/pages/Setting.tsx

+90-25
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,14 @@ export const Setting = () => {
3333
suggested_messages: "",
3434
});
3535
const [loadingState, setLoadingState] = useState({
36-
uploading: false,
3736
updating: false,
38-
removing: false,
37+
avatarUploading: false,
38+
avatarRemoving: false,
39+
chatIconUploading: false,
40+
chatIconRemoving: false,
3941
});
40-
const fileSelector = useRef<HTMLInputElement>(null);
42+
const avatarFileSelector = useRef<HTMLInputElement>(null);
43+
const chatIconFileSelector = useRef<HTMLInputElement>(null);
4144

4245
useEffect(() => {
4346
getBotSettings().then((res) => {
@@ -67,36 +70,51 @@ export const Setting = () => {
6770
setLoadingState((prev) => ({ ...prev, updating: true }));
6871
try {
6972
await updateBotSettings(settings);
73+
toast.success("Settings updated successfully.");
7074
} catch (error) {
71-
toast.error("Failed to update settings. Please try again.");
75+
toast.error(
76+
(error as any).message || "Failed to update settings. Please try again."
77+
);
7278
}
7379
setLoadingState((prev) => ({ ...prev, updating: false }));
7480
};
7581

76-
const onFileSelected = async (file?: File) => {
82+
const onFileSelected = async (
83+
field: "bot_avatar" | "chat_icon",
84+
file?: File
85+
) => {
7786
if (!file) return;
78-
setLoadingState((prev) => ({ ...prev, uploading: true }));
87+
const loadingField =
88+
field === "bot_avatar" ? " avatarRemoving" : "chatIconRemoving";
89+
setLoadingState((prev) => ({ ...prev, [loadingField]: true }));
7990
try {
8091
const {
8192
data: { picture_url },
8293
} = await uploadPicture(file);
83-
await updateBotSettings({ ...settings, bot_avatar: picture_url });
84-
setSettings((prev) => ({ ...prev, bot_avatar: picture_url }));
94+
await updateBotSettings({ ...settings, [field]: picture_url });
95+
setSettings((prev) => ({ ...prev, [field]: picture_url }));
96+
toast.success("Image updated successfully.");
8597
} catch (error) {
86-
toast.error("Failed to upload image. Please try again.");
98+
toast.error(
99+
(error as any).message || "Failed to upload image. Please try again."
100+
);
87101
}
88-
setLoadingState((prev) => ({ ...prev, uploading: false }));
102+
setLoadingState((prev) => ({ ...prev, [loadingField]: false }));
89103
};
90104

91-
const removeAvatar = async () => {
92-
setLoadingState((prev) => ({ ...prev, removing: true }));
105+
const removeImageField = async (field: "bot_avatar" | "chat_icon") => {
106+
const loadingField =
107+
field === "bot_avatar" ? " avatarRemoving" : "chatIconRemoving";
108+
setLoadingState((prev) => ({ ...prev, [loadingField]: true }));
93109
try {
94-
await updateBotSettings({ ...settings, bot_avatar: "" });
95-
setSettings((prev) => ({ ...prev, bot_avatar: "" }));
110+
await updateBotSettings({ ...settings, [field]: "" });
111+
setSettings((prev) => ({ ...prev, [field]: "" }));
96112
} catch (error) {
97-
toast.error("Failed to remove image. Please try again.");
113+
toast.error(
114+
(error as any).message || "Failed to remove image. Please try again."
115+
);
98116
}
99-
setLoadingState((prev) => ({ ...prev, removing: false }));
117+
setLoadingState((prev) => ({ ...prev, [loadingField]: false }));
100118
};
101119

102120
return (
@@ -111,7 +129,7 @@ export const Setting = () => {
111129
<SelectContent>
112130
<SelectGroup>
113131
<SelectLabel>{settings.model}</SelectLabel>
114-
<SelectItem value="gpt-3.5-turbor">gpt-3.5-turbor</SelectItem>
132+
<SelectItem value="gpt-3.5-turbo">gpt-3.5-turbo</SelectItem>
115133
</SelectGroup>
116134
</SelectContent>
117135
</Select>
@@ -153,6 +171,51 @@ export const Setting = () => {
153171
/>
154172
</div>
155173

174+
<div className="flex items-center">
175+
<Avatar>
176+
<AvatarFallback></AvatarFallback>
177+
<AvatarImage src={settings.bot_avatar} alt={settings.bot_name} />
178+
</Avatar>
179+
<div className="ml-6">
180+
<small className="text-sm font-medium leading-none">
181+
Profile Picture
182+
</small>
183+
<div className="mt-1 mb-3">
184+
<div className="flex items-center space-x-3">
185+
<Button
186+
className="h-7 px-3 text-xs"
187+
variant="outline"
188+
loading={loadingState.avatarUploading}
189+
onClick={() => avatarFileSelector.current?.click()}
190+
>
191+
<UploadIcon className="mr-2" />
192+
Upload image
193+
</Button>
194+
{settings.bot_avatar && (
195+
<Button
196+
className="h-7 px-3 text-xs"
197+
variant="ghost"
198+
loading={loadingState.avatarRemoving}
199+
onClick={() => removeImageField("bot_avatar")}
200+
>
201+
Remove
202+
</Button>
203+
)}
204+
</div>
205+
<Input
206+
className="hidden"
207+
accept="image/*"
208+
multiple={false}
209+
type="file"
210+
ref={avatarFileSelector}
211+
onChange={(e) =>
212+
onFileSelected("bot_avatar", e.target.files?.[0])
213+
}
214+
/>
215+
</div>
216+
</div>
217+
</div>
218+
156219
<small className="text-sm font-medium leading-none">Display name</small>
157220
<div className="mt-1 mb-3">
158221
<Input
@@ -168,7 +231,7 @@ export const Setting = () => {
168231
<div className="flex items-center">
169232
<Avatar>
170233
<AvatarFallback></AvatarFallback>
171-
<AvatarImage src={settings.bot_avatar} alt={settings.bot_name} />
234+
<AvatarImage src={settings.chat_icon} alt="Ask" />
172235
</Avatar>
173236
<div className="ml-6">
174237
<small className="text-sm font-medium leading-none">
@@ -179,18 +242,18 @@ export const Setting = () => {
179242
<Button
180243
className="h-7 px-3 text-xs"
181244
variant="outline"
182-
loading={loadingState.uploading}
183-
onClick={() => fileSelector.current?.click()}
245+
loading={loadingState.chatIconUploading}
246+
onClick={() => chatIconFileSelector.current?.click()}
184247
>
185248
<UploadIcon className="mr-2" />
186249
Upload image
187250
</Button>
188-
{settings.bot_avatar && (
251+
{settings.chat_icon && (
189252
<Button
190253
className="h-7 px-3 text-xs"
191254
variant="ghost"
192-
loading={loadingState.removing}
193-
onClick={removeAvatar}
255+
loading={loadingState.chatIconRemoving}
256+
onClick={() => removeImageField("chat_icon")}
194257
>
195258
Remove
196259
</Button>
@@ -201,8 +264,10 @@ export const Setting = () => {
201264
accept="image/*"
202265
multiple={false}
203266
type="file"
204-
ref={fileSelector}
205-
onChange={(e) => onFileSelected(e.target.files?.[0])}
267+
ref={chatIconFileSelector}
268+
onChange={(e) =>
269+
onFileSelected("chat_icon", e.target.files?.[0])
270+
}
206271
/>
207272
</div>
208273
</div>

src/pages/dashboard/Dashboard.tsx

+12-3
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,10 @@ export const Dashboard = () => {
103103
}));
104104
} catch (error) {
105105
if (!axios.isCancel(error)) {
106-
toast.error("Failed to fetch chat logs. Please try again.");
106+
toast.error(
107+
(error as any).message ||
108+
"Failed to fetch chat logs. Please try again."
109+
);
107110
setPageState((prev) => ({ ...prev, messageInitLoading: false }));
108111
}
109112
}
@@ -132,7 +135,10 @@ export const Dashboard = () => {
132135
conversationMoreLoading: false,
133136
}));
134137
} catch (error) {
135-
toast.error("Failed to fetch conversation list. Please try again.");
138+
toast.error(
139+
(error as any).message ||
140+
"Failed to fetch conversation list. Please try again."
141+
);
136142
setPageState((prev) => ({ ...prev, conversationMoreLoading: false }));
137143
}
138144
};
@@ -165,7 +171,10 @@ export const Dashboard = () => {
165171
}));
166172
} catch (error) {
167173
if (!axios.isCancel(error)) {
168-
toast.error("Failed to fetch chat logs. Please try again.");
174+
toast.error(
175+
(error as any).message ||
176+
"Failed to fetch chat logs. Please try again."
177+
);
169178
setPageState((prev) => ({ ...prev, messageMoreLoading: false }));
170179
}
171180
}

src/pages/dashboard/ReviseDialog.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export function ReviseDialog({
4343
toast.success("Answer updated successfully.");
4444
internalOpenChange(false);
4545
} catch (error) {
46-
toast.error("Failed to update answer.");
46+
toast.error((error as any).message || "Failed to update answer.");
4747
}
4848
setLoading(false);
4949
};

src/pages/source/FilterLinksDialog.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ import {
2121

2222
export function FilterLinksDialog({
2323
site,
24+
onConfirm,
2425
onDialogClose,
2526
}: {
2627
site: string;
28+
onConfirm?: () => void;
2729
onDialogClose?: () => void;
2830
}) {
2931
const [dialogOpen, setDialogOpen] = useState(false);
@@ -95,6 +97,7 @@ export function FilterLinksDialog({
9597
try {
9698
await importCrawlData(links.map((link) => link.id));
9799
onOpenChange(false);
100+
setTimeout(() => onConfirm?.(), 1000);
98101
} catch (error) {
99102
setErrMessage("Failed to import links, please try again later.");
100103
}
@@ -115,7 +118,7 @@ export function FilterLinksDialog({
115118
</Button>
116119
</DialogTrigger>
117120
<DialogContent
118-
className="lg:min-w-[48rem]"
121+
className="sm:min-w-[48rem] sm:max-h-[80vh] flex flex-col"
119122
onPointerDownOutside={(e) => e.preventDefault()}
120123
>
121124
<DialogHeader>

0 commit comments

Comments
 (0)