- No tags yet
+ {t("No tags yet")}
)}
diff --git a/k-notes-frontend/src/components/bulk-actions-bar.tsx b/k-notes-frontend/src/components/bulk-actions-bar.tsx
index b7e0021..d788388 100644
--- a/k-notes-frontend/src/components/bulk-actions-bar.tsx
+++ b/k-notes-frontend/src/components/bulk-actions-bar.tsx
@@ -3,11 +3,13 @@ import { useDeleteNote, useUpdateNote } from "@/hooks/use-notes";
import { Button } from "@/components/ui/button";
import { Archive, Trash2, X } from "lucide-react";
import { toast } from "sonner";
+import { useTranslation } from "react-i18next";
export function BulkActionsBar() {
const { selectedIds, clearSelection, isBulkMode } = useBulkSelection();
const { mutate: deleteNote } = useDeleteNote();
const { mutate: updateNote } = useUpdateNote();
+ const { t } = useTranslation();
if (!isBulkMode) return null;
@@ -16,25 +18,25 @@ export function BulkActionsBar() {
ids.forEach((id) => {
updateNote({ id, is_archived: true });
});
- toast.success(`Archived ${ids.length} note${ids.length > 1 ? "s" : ""}`);
+ toast.success(t("Archived {{count}} note", { count: ids.length, defaultValue_other: "Archived {{count}} notes" }));
clearSelection();
};
const handleDeleteAll = () => {
- if (!confirm(`Are you sure you want to delete ${selectedIds.size} note(s)?`)) return;
+ if (!confirm(t("Are you sure you want to delete {{count}} note?", { count: selectedIds.size, defaultValue_other: "Are you sure you want to delete {{count}} notes?" }))) return;
const ids = Array.from(selectedIds);
ids.forEach((id) => {
deleteNote(id);
});
- toast.success(`Deleted ${ids.length} note${ids.length > 1 ? "s" : ""}`);
+ toast.success(t("Deleted {{count}} note", { count: ids.length, defaultValue_other: "Deleted {{count}} notes" }));
clearSelection();
};
return (
- {selectedIds.size} selected
+ {t("{{count}} selected", { count: selectedIds.size })}
@@ -46,7 +48,7 @@ export function BulkActionsBar() {
className="gap-2"
>
- Archive
+ {t("Archive")}
diff --git a/k-notes-frontend/src/components/create-note-dialog.tsx b/k-notes-frontend/src/components/create-note-dialog.tsx
index cf66295..eed9c92 100644
--- a/k-notes-frontend/src/components/create-note-dialog.tsx
+++ b/k-notes-frontend/src/components/create-note-dialog.tsx
@@ -5,6 +5,7 @@ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, Di
import { NoteForm } from "./note-form";
import { toast } from "sonner";
import { Plus } from "lucide-react";
+import { useTranslation } from "react-i18next";
interface CreateNoteDialogProps {
trigger?: React.ReactNode;
@@ -15,6 +16,7 @@ interface CreateNoteDialogProps {
export function CreateNoteDialog({ trigger, open: controlledOpen, onOpenChange }: CreateNoteDialogProps) {
const [internalOpen, setInternalOpen] = useState(false);
const { mutate: createNote, isPending } = useCreateNote();
+ const { t } = useTranslation();
// Support both controlled and uncontrolled modes
const isControlled = controlledOpen !== undefined;
@@ -29,7 +31,7 @@ export function CreateNoteDialog({ trigger, open: controlledOpen, onOpenChange }
createNote({ ...data, tags }, {
onSuccess: () => {
- toast.success("Note created");
+ toast.success(t("Note created"));
setOpen(false);
},
onError: (error: any) => {
@@ -41,7 +43,7 @@ export function CreateNoteDialog({ trigger, open: controlledOpen, onOpenChange }
const defaultTrigger = (
);
@@ -59,12 +61,12 @@ export function CreateNoteDialog({ trigger, open: controlledOpen, onOpenChange }
)}
- Create Note
+ {t("Create Note")}
- Add a new note to your collection.
+ {t("Add a new note to your collection.")}
-
+
);
diff --git a/k-notes-frontend/src/components/language-switcher.tsx b/k-notes-frontend/src/components/language-switcher.tsx
new file mode 100644
index 0000000..0ff3a8f
--- /dev/null
+++ b/k-notes-frontend/src/components/language-switcher.tsx
@@ -0,0 +1,40 @@
+import { useTranslation } from "react-i18next";
+import { Label } from "@/components/ui/label";
+import { Button } from "@/components/ui/button";
+import { Languages } from "lucide-react";
+
+const LANGUAGES = [
+ { code: "en", label: "English" },
+ { code: "pl", label: "Polski" },
+];
+
+export function LanguageSwitcher() {
+ const { i18n, t } = useTranslation();
+
+ const changeLanguage = (languageCode: string) => {
+ i18n.changeLanguage(languageCode);
+ };
+
+ return (
+
+
+
+
+ {LANGUAGES.map((lang) => (
+
+ ))}
+
+
+
+ );
+}
diff --git a/k-notes-frontend/src/components/note-card.tsx b/k-notes-frontend/src/components/note-card.tsx
index 7365d7c..05b74da 100644
--- a/k-notes-frontend/src/components/note-card.tsx
+++ b/k-notes-frontend/src/components/note-card.tsx
@@ -16,6 +16,7 @@ import { VersionHistoryDialog } from "./version-history-dialog";
import { NoteViewDialog } from "./note-view-dialog";
import { Checkbox } from "@/components/ui/checkbox";
import { useBulkSelection } from "@/components/bulk-selection-context";
+import { useTranslation } from "react-i18next";
interface NoteCardProps {
note: Note;
@@ -27,6 +28,7 @@ export function NoteCard({ note }: NoteCardProps) {
const [editing, setEditing] = useState(false);
const [historyOpen, setHistoryOpen] = useState(false);
const [viewOpen, setViewOpen] = useState(false);
+ const { t } = useTranslation();
// Bulk selection
const { isSelected, toggleSelection, isBulkMode } = useBulkSelection();
@@ -57,7 +59,7 @@ export function NoteCard({ note }: NoteCardProps) {
const handleDelete = (e: React.MouseEvent) => {
e.stopPropagation();
- if (confirm("Are you sure?")) {
+ if (confirm(t("Are you sure?"))) {
deleteNote(note.id);
}
}
@@ -74,7 +76,7 @@ export function NoteCard({ note }: NoteCardProps) {
}, {
onSuccess: () => {
setEditing(false);
- toast.success("Note updated");
+ toast.success(t("Note updated"));
}
});
}
@@ -129,7 +131,7 @@ export function NoteCard({ note }: NoteCardProps) {
))}