Skip to content

Commit

Permalink
Merge pull request #264 from priyanshuverma-dev/feat-i18n
Browse files Browse the repository at this point in the history
feat: i18n Added for 5 langs
  • Loading branch information
kom-senapati authored Nov 4, 2024
2 parents fc2302f + 3da2663 commit aa6c819
Show file tree
Hide file tree
Showing 37 changed files with 1,457 additions and 243 deletions.
Binary file modified client/bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@
"cmdk": "1.0.0",
"emoji-picker-react": "^4.12.0",
"export-from-json": "^1.7.4",
"i18next": "^23.16.4",
"lucide-react": "^0.453.0",
"moment": "^2.30.1",
"next-themes": "^0.3.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.53.1",
"react-hot-toast": "^2.4.1",
"react-i18next": "^15.1.0",
"react-markdown": "^9.0.1",
"react-router-dom": "^6.27.0",
"react-scroll-to-top": "^3.0.0",
Expand Down
12 changes: 7 additions & 5 deletions client/src/components/ChatbotCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Card, CardContent, CardFooter, CardHeader } from "./ui/card";
import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar";
import { Button } from "./ui/button";
import { Link, useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";

export function ChatbotCard({
chatbot,
Expand All @@ -16,6 +17,7 @@ export function ChatbotCard({
}) {
const shareModel = useShareModal();
const rq = useQueryClient();
const { t } = useTranslation();
const navigate = useNavigate();
const likeMutation = useMutation({
mutationFn: likeAndReport,
Expand All @@ -40,7 +42,7 @@ export function ChatbotCard({
{chatbot.latest_version.name}
</h2>
<p className="text-sm text-muted-foreground">
Created by @{chatbot.latest_version.modified_by}
{t("created_by")}@{chatbot.latest_version.modified_by}
</p>
</div>
</CardHeader>
Expand All @@ -64,7 +66,7 @@ export function ChatbotCard({
}
>
<Heart className="h-4 w-4" />
<span className="sr-only">Like</span>
<span className="sr-only">{t("like")}</span>
</Button>
<span
className="inline-flex items-center text-sm text-muted-foreground"
Expand All @@ -84,7 +86,7 @@ export function ChatbotCard({
}
>
<Flag className="h-4 w-4" />
<span className="sr-only">Report</span>
<span className="sr-only">{t("report")}</span>
</Button>
<span
className="inline-flex items-center text-sm text-muted-foreground"
Expand All @@ -99,7 +101,7 @@ export function ChatbotCard({
onClick={() => navigate(`/chatbot/${chatbot.id}`)}
>
<MessageSquare className="h-4 w-4 mr-1" />
Chat
{t("chat")}
</Button>
<Button
variant="outline"
Expand All @@ -112,7 +114,7 @@ export function ChatbotCard({
}
>
<Share2 className="h-4 w-4" />
<span className="sr-only">Share</span>
<span className="sr-only">{t("share")}</span>
</Button>
</div>
</CardFooter>
Expand Down
4 changes: 3 additions & 1 deletion client/src/components/ImageCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Card, CardContent, CardFooter, CardHeader } from "./ui/card";
import { Button } from "./ui/button";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { likeAndReport } from "@/lib/queries";
import { useTranslation } from "react-i18next";

export function ImageCard({
image,
Expand All @@ -13,6 +14,7 @@ export function ImageCard({
queryKeys: string[];
}) {
const qc = useQueryClient();
const { t } = useTranslation();
const mutation = useMutation({
mutationFn: likeAndReport,
onSuccess: () => qc.invalidateQueries({ queryKey: queryKeys }),
Expand Down Expand Up @@ -73,7 +75,7 @@ export function ImageCard({
>
<Button variant="ghost" size="sm">
<Download className="h-4 w-4 mr-2" />
Download
{t("download")}
</Button>
</a>
</CardFooter>
Expand Down
2 changes: 0 additions & 2 deletions client/src/components/LikeAndReport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export function LikeAndReport({
queryKeys: string[];
}) {
const qc = useQueryClient();

const mutation = useMutation({
mutationFn: likeAndReport,
onSuccess: () => qc.invalidateQueries({ queryKey: queryKeys }),
Expand Down Expand Up @@ -59,7 +58,6 @@ export function LikeAndReport({
}
>
<Ban />
{/* Display reports count on top of the button */}
<span className="absolute -bottom-2 -right-2 bg-red-500 text-white text-xs rounded-full px-1.5 py-0.5">
{reports}
</span>
Expand Down
59 changes: 50 additions & 9 deletions client/src/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,33 @@ import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuPortal,
DropdownMenuSeparator,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { useSettingsModal } from "@/stores/modal-store";
import { useTranslation } from "react-i18next";

const languages = [
{ label: "English", code: "en" },
{ label: "हिन्दी", code: "hi" },
{ label: "Español", code: "es" },
{ label: "Français", code: "fr" },
{ label: "日本語", code: "ja" },
];

export default function Navbar() {
const { user, loading, logout } = useAuth();
const settingsModal = useSettingsModal();
const { t, i18n } = useTranslation();

const changeLanguage = (lng: string) => {
i18n.changeLanguage(lng);
};

return (
<nav className="flex justify-between items-center px-6 py-4 rounded-md border-b-2 dark:border-darker border-lighter">
<Link to="/dashboard" className="text-5xl brand font-extrabold">
Expand All @@ -25,25 +44,25 @@ export default function Navbar() {
<ul className="flex space-x-6 items-center">
<li>
<Link to="/leaderboard" className="py-2">
Leaderboard
{t("navbar.leaderboard")}
</Link>
</li>
<li>
<Link to="/hub" className="py-2">
Hub
{t("navbar.hub")}
</Link>
</li>

{user == null ? (
<>
<li className="w-full">
<Link to="/signup" className="py-2">
SignUp
{t("navbar.sign_up")}
</Link>
</li>
<li className="w-full ">
<Link to="/login" className="py-2">
LogIn
{t("navbar.login")}
</Link>
</li>
</>
Expand All @@ -60,27 +79,49 @@ export default function Navbar() {
</DropdownMenuTrigger>
<DropdownMenuContent>
<Link to={`/profile/${user.username}`}>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>
{t("navbar.profile")}
</DropdownMenuItem>
</Link>

<Link to={`/images`}>
<DropdownMenuItem>My Images</DropdownMenuItem>
<DropdownMenuItem>
{t("navbar.my_images")}
</DropdownMenuItem>
</Link>
<Link to={`/chatbots`}>
<DropdownMenuItem>My Chatbots</DropdownMenuItem>
<DropdownMenuItem>
{t("navbar.my_chatbots")}
</DropdownMenuItem>
</Link>
<DropdownMenuSeparator />
<DropdownMenuItem
onClick={() => settingsModal.onOpen()}
>
Settings
{t("navbar.settings")}
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
{t("navbar.language")}
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
{languages.map((lang) => (
<DropdownMenuItem
onClick={() => changeLanguage(lang.code)}
>
{lang.label}
</DropdownMenuItem>
))}
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuSeparator />
<DropdownMenuItem
onClick={() => logout()}
className="text-destructive hover:text-destructive/10 focus:text-destructive/90 focus:bg-destructive/10"
>
Log out
{t("navbar.logout")}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
Expand Down
14 changes: 7 additions & 7 deletions client/src/components/modals/Tts-magic-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import toast from "react-hot-toast";
import { Textarea } from "../ui/textarea";

import { AudioLines, Download, X } from "lucide-react";
import { useTranslation } from "react-i18next";

const markdownToPlainText = (markdown: string) => {
return markdown
Expand All @@ -34,7 +35,7 @@ const markdownToPlainText = (markdown: string) => {
export default function TtsMagicModal() {
const modal = useTtsMagicModal();
const initialText = modal.extras.text || "";

const { t } = useTranslation();
const [text, setText] = useState("");
const [loading, setLoading] = useState(false);

Expand Down Expand Up @@ -93,7 +94,7 @@ export default function TtsMagicModal() {
<AlertDialogHeader>
<AlertDialogTitle>
<div className="flex items-center justify-between">
<p>Convert Text to speech and download</p>
<p>{t("tts_modal.title")}</p>
<Button
variant={"outline"}
size={"icon"}
Expand All @@ -105,8 +106,7 @@ export default function TtsMagicModal() {
</div>
</AlertDialogTitle>
<AlertDialogDescription>
text is converted to audio file in mp3 format that will be
downloaded automatically.
{t("tts_modal.sub_title")}
</AlertDialogDescription>
<div className="my-4">
<Textarea
Expand All @@ -115,7 +115,7 @@ export default function TtsMagicModal() {
onChange={(e) => setText(e.target.value)} // Update state on change
rows={5}
className="w-full p-2 border rounded"
placeholder="Enter text here..."
placeholder={t("tts_modal.text")}
/>
</div>
</AlertDialogHeader>
Expand All @@ -126,15 +126,15 @@ export default function TtsMagicModal() {
className="btn btn-secondary ml-2"
variant={"secondary"}
>
<Download /> Text
<Download /> {t("tts_modal.text")}
</Button>
<Button
disabled={loading}
onClick={downloadAudio}
className="btn btn-primary"
>
<AudioLines />
{loading ? "Generating..." : "Generate"}
{loading ? t("tts_modal.generating") : t("tts_modal.generate")}
</Button>
</AlertDialogFooter>
</AlertDialogContent>
Expand Down
38 changes: 14 additions & 24 deletions client/src/components/modals/command-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ import {
useTtsMagicModal,
} from "@/stores/modal-store";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";

export function CommandModal() {
const [open, setOpen] = React.useState(false);

const { t } = useTranslation();
const createBotModal = useCreateChatbotModal();
const settingsModal = useSettingsModal();
const imagineModal = useImagineModal();
Expand All @@ -54,37 +55,26 @@ export function CommandModal() {

return (
<>
<div className="flex justify-between p-1">
<p className="text-sm text-muted-foreground font-mono ">
Open Command Panel
</p>
<p className="text-sm text-muted-foreground">
Press{" "}
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100">
<span className="text-xs"></span>K
</kbd>
</p>
</div>
<CommandDialog open={open} onOpenChange={setOpen}>
<CommandInput placeholder="Type a command or search..." />
<CommandInput placeholder={t("commandbox.input_ph")} />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandEmpty>{t("commandbox.no_result")}</CommandEmpty>
<CommandGroup heading="Suggestions">
<CommandItem onSelect={() => createBotModal.onOpen()}>
<Plus />
<span>Create Chatbot</span>
<span>{t("commandbox.create_chatbot")}</span>
</CommandItem>
<CommandItem onSelect={() => ttsModal.onOpen({ text: "" })}>
<AudioWaveform />
<span>Text-to-Speech Magic</span>
<span>{t("commandbox.tts")}</span>
</CommandItem>
<CommandItem onSelect={() => translateModal.onOpen({ text: "" })}>
<Languages />
<span>Translate Magic</span>
<span>{t("commandbox.translate")}</span>
</CommandItem>
<CommandItem onSelect={() => imagineModal.onOpen()}>
<Image />
<span>Generate Images</span>
<span>{t("commandbox.image_generation")}</span>
</CommandItem>
<CommandItem
onSelect={() => {
Expand All @@ -93,19 +83,19 @@ export function CommandModal() {
}}
>
<Bot />
<span>Anonymous Chat</span>
<span>{t("commandbox.anonymous_chat")}</span>
</CommandItem>
</CommandGroup>
<CommandSeparator />
<CommandGroup heading="Socialize">
<CommandGroup heading={t("commandbox.socialize")}>
<CommandItem
onSelect={() => {
setOpen(false);
navigate("/hub");
}}
>
<PanelTopInactive />
<span>Marketplace Hub</span>
<span>{t("commandbox.hub")}</span>
</CommandItem>
<CommandItem
onSelect={() => {
Expand All @@ -114,13 +104,13 @@ export function CommandModal() {
}}
>
<ChartColumn />
<span>Leaderboard</span>
<span>{t("navbar.leaderboard")}</span>
</CommandItem>
</CommandGroup>
<CommandGroup heading="Settings">
<CommandGroup heading={t("navbar.settings")}>
<CommandItem onSelect={() => settingsModal.onOpen()}>
<GearIcon />
<span>Settings</span>
<span>{t("navbar.settings")}</span>
</CommandItem>
</CommandGroup>
</CommandList>
Expand Down
Loading

0 comments on commit aa6c819

Please sign in to comment.