Skip to content

Better API Key Input hints #3086

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions apps/upskii/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@
"api-key-valid-desc": "API Key succesfully validated and has been saved",
"api-key-invalid-title": "Invalid API Key",
"api-key-invalid-desc": "Please provide a valid API Key or try again",
"api-key-required": "Please provide a valid key format",
"api-key-required-format": "Please provide a valid key format",
"api-key-saved-title": "API key saved",
"api-key-saved-desc": "Your API Key has been saved. Please refresh the page to start using the AI.",
"validate": "Validate",
Expand All @@ -220,7 +220,9 @@
"api_input_description": "Input your API Key to access AI features",
"delete-api-key": "Delete API Key",
"api-key-deleted-title": "API Key Deleted",
"api-key-deleted-desc": "Your API Key has been successfully deleted"
"api-key-deleted-desc": "Your API Key has been successfully deleted",
"api-key-required": "Please provide your API Key to continue",
"get-api-key-from": "Get your API Key from"
},
"api-key-data-table": {
"id": "ID",
Expand Down
10 changes: 6 additions & 4 deletions apps/upskii/messages/vi.json
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@
"api-key-invalid-title": "API Key không hợp lệ",
"api-key-valid-title": "API Key hợp lệ",
"api-key-invalid-desc": "Vui lòng cung cấp API Key hợp lệ hoặc thử lại",
"api-key-required": "Vui lòng cung cấp một định dạng hợp lệ",
"api-key-required-format": "Vui lòng cung cấp một định dạng hợp lệ",
"api-key-saved-title": "Key API được lưu",
"validate": "Kiểm tra",
"save-api-key": "Lưu trữ",
Expand All @@ -220,7 +220,9 @@
"api_input_description": "Nhập chìa khóa API của bạn để sử dụng những tính năng AI",
"delete-api-key": "Xóa chìa khóa API",
"api-key-deleted-title": "Chìa khóa API đã được xóa",
"api-key-deleted-desc": "Chìa khóa API của bạn đã được xóa"
"api-key-deleted-desc": "Chìa khóa API của bạn đã được xóa",
"api-key-required": "Vui lòng cung cấp khóa API của bạn để tiếp tục",
"get-api-key-from": "Nhận khóa API của bạn từ"
},
"api-key-data-table": {
"id": "Mã số",
Expand Down Expand Up @@ -1824,7 +1826,7 @@
"answer5": "Nền tảng này có khả năng tùy biến cao với các tùy chọn gắn nhãn trắng, nhãn hiệu tùy chỉnh, quy trình công việc có thể định cấu hình và tích hợp API. \nBạn có thể điều chỉnh trải nghiệm học tập để phù hợp với nhu cầu của tổ chức bạn.",
"question6": "Các yêu cầu phần cứng là gì?",
"answer6": "Nền tảng dựa trên đám mây của chúng tôi hoạt động trên mọi trình duyệt web hiện đại. \nĐể tổ chức hội nghị truyền hình tối ưu, chúng tôi khuyên bạn nên kết nối Internet ổn định và cập nhật các thiết bị có chức năng camera và micrô.",
"question7": "Việc sao lưu dữ liệu được xử lí như thế nào?",
"question7": "Việc sao lưu dữ liệu ược xử lí như thế nào?",
"answer7": "Chúng tôi duy trì các bản sao lưu tự động hàng ngày với khả năng lưu giữ trong 30 ngày, lưu trữ dự phòng theo địa lý và các giao thức khắc phục thảm họa. \nDữ liệu của bạn luôn an toàn và có thể truy cập được."
}
}
Expand Down Expand Up @@ -2905,7 +2907,7 @@
"change-password-description": "Đổi mật khẩu của bạn.",
"delete-account": "Xóa tài khoản",
"delete-account-description": "Xóa tài khoản của bạn.",
"delete-account-message": "Tài khoản của bạn sẽ bị xoá vĩnh viễn và không thể phục hồi. Nhập địa chỉ email của bạn để xác nhận xoá tài khoản.",
"delete-account-message": "Tài khoản của bạn sẽ bị xóa vĩnh viễn và không thể phục hồi. Nhập địa chỉ email của bạn để xác nhận xoá tài khoản.",
"new_avatar": "Hình đại diện mới",
"upload_avatar": "Hình đại diện mới",
"remove_avatar": "Xóa hình đại diện",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,12 @@
{t('common.coming_soon')} ✨
</div>
) : (
<EmptyScreen chats={chats} setInput={setInput} locale={locale} />
<EmptyScreen
chats={chats}
setInput={setInput}
locale={locale}
hasApiKey={!!initialApiKey}
/>

Check warning on line 339 in apps/upskii/src/app/[locale]/(dashboard)/[wsId]/ai-chat/chat.tsx

View check run for this annotation

Codecov / codecov/patch

apps/upskii/src/app/[locale]/(dashboard)/[wsId]/ai-chat/chat.tsx#L334-L339

Added lines #L334 - L339 were not covered by tests
)}
</div>

Expand Down
27 changes: 22 additions & 5 deletions apps/upskii/src/components/chat-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
DialogTitle,
} from '@tuturuuu/ui/dialog';
import { useTranslations } from 'next-intl';
import Link from 'next/link';

Check warning on line 20 in apps/upskii/src/components/chat-panel.tsx

View check run for this annotation

Codecov / codecov/patch

apps/upskii/src/components/chat-panel.tsx#L20

Added line #L20 was not covered by tests
import React, { useState } from 'react';

interface PresenceUser {
Expand Down Expand Up @@ -189,11 +190,27 @@
: t('chat_visibility')}
</DialogTitle>
<DialogDescription>
{dialogType === 'files'
? t('upload_file_description')
: dialogType === 'api'
? t('api_input_description')
: t('chat_visibility_description')}
{dialogType === 'files' ? (
t('upload_file_description')
) : dialogType === 'api' ? (
<span className="flex flex-col gap-2">
{t('api_input_description')}
<br />
<span className="flex items-center gap-2">
{t('get-api-key-from')}:
<Link
href="https://aistudio.google.com/app/apikey"
target="_blank"
rel="noopener noreferrer"
className="text-primary underline hover:no-underline"
>

Check warning on line 206 in apps/upskii/src/components/chat-panel.tsx

View check run for this annotation

Codecov / codecov/patch

apps/upskii/src/components/chat-panel.tsx#L193-L206

Added lines #L193 - L206 were not covered by tests
Google AI Studio
</Link>
</span>
</span>

Check warning on line 210 in apps/upskii/src/components/chat-panel.tsx

View check run for this annotation

Codecov / codecov/patch

apps/upskii/src/components/chat-panel.tsx#L208-L210

Added lines #L208 - L210 were not covered by tests
) : (
t('chat_visibility_description')

Check warning on line 212 in apps/upskii/src/components/chat-panel.tsx

View check run for this annotation

Codecov / codecov/patch

apps/upskii/src/components/chat-panel.tsx#L212

Added line #L212 was not covered by tests
)}
</DialogDescription>
</DialogHeader>

Expand Down
11 changes: 10 additions & 1 deletion apps/upskii/src/components/empty-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@
import 'dayjs/locale/vi';
import relativeTime from 'dayjs/plugin/relativeTime';
import { useTranslations } from 'next-intl';
import { toast } from 'sonner';

Check warning on line 17 in apps/upskii/src/components/empty-screen.tsx

View check run for this annotation

Codecov / codecov/patch

apps/upskii/src/components/empty-screen.tsx#L17

Added line #L17 was not covered by tests

export function EmptyScreen({
// chats,
setInput,
locale,
hasApiKey,

Check warning on line 23 in apps/upskii/src/components/empty-screen.tsx

View check run for this annotation

Codecov / codecov/patch

apps/upskii/src/components/empty-screen.tsx#L23

Added line #L23 was not covered by tests
}: Pick<UseChatHelpers, 'setInput'> & {
chats?: AIChat[];
locale: string;
hasApiKey: boolean;
}) {
dayjs.extend(relativeTime);
dayjs.locale(locale);
Expand Down Expand Up @@ -93,7 +96,13 @@
'w-full items-center justify-center gap-2 border p-2 text-left text-sm md:p-8',
message.color
)}
onClick={() => setInput(message.message)}
onClick={() => {
if (hasApiKey) {
setInput(message.message);
} else {
toast.error(t('api_key_required'));
}
}}

Check warning on line 105 in apps/upskii/src/components/empty-screen.tsx

View check run for this annotation

Codecov / codecov/patch

apps/upskii/src/components/empty-screen.tsx#L99-L105

Added lines #L99 - L105 were not covered by tests
>
{message.icon}
<div className="line-clamp-1 break-all whitespace-normal">
Expand Down
4 changes: 3 additions & 1 deletion apps/upskii/src/components/form-apikey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
apiKey: z
.string()
.min(1, { message: t('api-key-required') })
.regex(/^AIza[0-9A-Za-z\-_]{35}$/, { message: t('api-key-required') }),
.regex(/^AIza[0-9A-Za-z\-_]{35}$/, {
message: t('api-key-required-format'),
}),

Check warning on line 44 in apps/upskii/src/components/form-apikey.tsx

View check run for this annotation

Codecov / codecov/patch

apps/upskii/src/components/form-apikey.tsx#L42-L44

Added lines #L42 - L44 were not covered by tests
});

const form = useForm({
Expand Down
4 changes: 2 additions & 2 deletions apps/upskii/src/components/prompt-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -734,8 +734,8 @@
onChange={(e) => setInput(e.target.value)}
placeholder={
disabled || !apiKey
? t('ai_chat.imagine_placeholder')
: `${t('ai_chat.send_message')}.`
? t('ai_chat.api_key_required')
: `${t('ai_chat.send_message')}`

Check warning on line 738 in apps/upskii/src/components/prompt-form.tsx

View check run for this annotation

Codecov / codecov/patch

apps/upskii/src/components/prompt-form.tsx#L737-L738

Added lines #L737 - L738 were not covered by tests
}
spellCheck={false}
maxRows={7}
Expand Down