From ae99ba5e6f3b22a8b24139c308f546e5d24b467b Mon Sep 17 00:00:00 2001 From: erfan-goodarzi Date: Wed, 16 Jul 2025 16:30:57 +0330 Subject: [PATCH 1/3] feat: add folder password input --- .../components/modal/add-bookmark.modal.tsx | 23 +++++++++++++++++-- src/layouts/bookmark/components/shared.tsx | 1 + 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/layouts/bookmark/components/modal/add-bookmark.modal.tsx b/src/layouts/bookmark/components/modal/add-bookmark.modal.tsx index b97fae4a..4dae5b72 100644 --- a/src/layouts/bookmark/components/modal/add-bookmark.modal.tsx +++ b/src/layouts/bookmark/components/modal/add-bookmark.modal.tsx @@ -42,6 +42,7 @@ export function AddBookmarkModal({ customBackground: '', customTextColor: '', sticker: '', + password: '', }) const { fileInputRef, setIconLoadError, renderIconPreview, handleImageUpload } = @@ -93,7 +94,11 @@ export function AddBookmarkModal({ if (type === 'FOLDER') { //@ts-ignore - onAdd({ ...baseBookmark, onlineId: null } as Bookmark) + onAdd({ + ...baseBookmark, + onlineId: null, + password: formData.password, + } as Bookmark) } else { let newUrl = formData.url if (!newUrl.startsWith('http://') && !newUrl.startsWith('https://')) { @@ -186,7 +191,7 @@ export function AddBookmarkModal({ -
+
{' '}
{type === 'BOOKMARK' && ( @@ -222,6 +227,20 @@ export function AddBookmarkModal({ 'mt-2 w-full px-4 py-3 text-right rounded-lg transition-all duration-200 ' } /> + {type === 'FOLDER' && ( +
+ updateFormData('password', v)} + className={ + 'mt-2 w-full px-4 py-3 text-right absolute rounded-lg transition-all duration-300' + } + /> +
+ )}
{type === 'BOOKMARK' && ( Date: Wed, 16 Jul 2025 16:31:38 +0330 Subject: [PATCH 2/3] feat: implement folder password modal --- src/layouts/bookmark/bookmarks.tsx | 49 +++++++++---- .../bookmark/components/bookmark-folder.tsx | 15 +++- .../modal/folder-password.modal.tsx | 71 +++++++++++++++++++ src/layouts/bookmark/types/bookmark.types.ts | 2 + 4 files changed, 122 insertions(+), 15 deletions(-) create mode 100644 src/layouts/bookmark/components/modal/folder-password.modal.tsx diff --git a/src/layouts/bookmark/bookmarks.tsx b/src/layouts/bookmark/bookmarks.tsx index a5cbda15..16eb7601 100644 --- a/src/layouts/bookmark/bookmarks.tsx +++ b/src/layouts/bookmark/bookmarks.tsx @@ -10,6 +10,7 @@ import { AddBookmarkModal } from './components/modal/add-bookmark.modal' import { BookmarkContextMenu } from './components/modal/bookmark-context-menu' import { EditBookmarkModal } from './components/modal/edit-bookmark.modal' import type { Bookmark, FolderPathItem } from './types/bookmark.types' +import { FolderPasswordModal } from './components/modal/folder-password.modal' export function BookmarksComponent() { const { @@ -23,19 +24,17 @@ export function BookmarksComponent() { const [showAddBookmarkModal, setShowAddBookmarkModal] = useState(false) const [showEditBookmarkModal, setShowEditBookmarkModal] = useState(false) + const [showFolderPasswordModal, setShowFolderPasswordModal] = useState(false) const [bookmarkToEdit, setBookmarkToEdit] = useState(null) + const [folderPassword, setFolderPassword] = useState('') + const [folderToOpen, setFolderToOpen] = useState(null) const [selectedBookmark, setSelectedBookmark] = useState(null) - const [contextMenuPos, setContextMenuPos] = useState({ x: 0, y: 0 }) - const [currentFolderId, setCurrentFolderId] = useState(null) - const [folderPath, setFolderPath] = useState([]) - const [currentFolderIsManageable, setCurrentFolderIsManageable] = useState(true) - const [draggedBookmarkId, setDraggedBookmarkId] = useState(null) const [dragOverIndex, setDragOverIndex] = useState(null) @@ -92,6 +91,21 @@ export function BookmarksComponent() { setShowEditBookmarkModal(true) setSelectedBookmark(null) } + + const handleOpenFolder = (bookmark: Bookmark, e?: React.MouseEvent) => { + if (e?.ctrlKey || e?.metaKey) { + openBookmarks(bookmark) + } else { + setCurrentFolderId(bookmark.id) + setFolderPath([ + ...folderPath, + { id: bookmark.id, title: bookmark.title, password: bookmark.password }, + ]) + + setCurrentFolderIsManageable(isManageable(bookmark)) + } + } + const handleBookmarkClick = (bookmark: Bookmark, e?: React.MouseEvent) => { if (e) { e.preventDefault() @@ -109,13 +123,12 @@ export function BookmarksComponent() { } if (bookmark.type === 'FOLDER') { - if (e?.ctrlKey || e?.metaKey) { - openBookmarks(bookmark) + setFolderPassword(bookmark.password ?? '') + if (bookmark.password) { + setFolderToOpen(bookmark) + setShowFolderPasswordModal(true) } else { - setCurrentFolderId(bookmark.id) - setFolderPath([...folderPath, { id: bookmark.id, title: bookmark.title }]) - - setCurrentFolderIsManageable(isManageable(bookmark)) + handleOpenFolder(bookmark, e) } } else { if (e?.ctrlKey || e?.metaKey) { @@ -283,7 +296,11 @@ export function BookmarksComponent() { bookmark ? (
+ { + if (folderToOpen) handleOpenFolder(folderToOpen) + }} + folderPassword={folderPassword} + isOpen={showFolderPasswordModal} + onClose={() => setShowFolderPasswordModal(false)} + /> setShowAddBookmarkModal(false)} diff --git a/src/layouts/bookmark/components/bookmark-folder.tsx b/src/layouts/bookmark/components/bookmark-folder.tsx index e139cc2f..db1e89dd 100644 --- a/src/layouts/bookmark/components/bookmark-folder.tsx +++ b/src/layouts/bookmark/components/bookmark-folder.tsx @@ -2,6 +2,7 @@ import { addOpacityToColor } from '@/common/color' import Tooltip from '@/components/toolTip' import { useState } from 'react' import { FaFolder, FaFolderOpen } from 'react-icons/fa' +import { LuFolderLock } from 'react-icons/lu' import { SlOptions } from 'react-icons/sl' import type { Bookmark } from '../types/bookmark.types' import { RenderStickerPattern } from './bookmark/bookmark-sticker' @@ -37,7 +38,11 @@ export function FolderBookmarkItem({ const displayIcon = bookmark.customImage || (isHovered ? ( - + bookmark.password ? ( + + ) : ( + + ) ) : ( )) @@ -58,14 +63,18 @@ export function FolderBookmarkItem({ onDrop={onDrop} className={`relative ${isDragging ? 'opacity-50' : ''}`} > - + +
+ {errorMessage && ( +

+ {errorMessage} +

+ )} + + ) +} diff --git a/src/layouts/bookmark/types/bookmark.types.ts b/src/layouts/bookmark/types/bookmark.types.ts index ea5e5389..c96e83d4 100644 --- a/src/layouts/bookmark/types/bookmark.types.ts +++ b/src/layouts/bookmark/types/bookmark.types.ts @@ -15,9 +15,11 @@ export interface Bookmark { customTextColor?: string sticker?: string order?: number + password?: string } export interface FolderPathItem { id: string title: string + password?: string; } From 3f9ec0cba8f39d833d27c30917fb1219741523d6 Mon Sep 17 00:00:00 2001 From: erfan-goodarzi Date: Wed, 16 Jul 2025 16:32:05 +0330 Subject: [PATCH 3/3] feat: add pasword input to edit folder modal --- .../components/modal/edit-bookmark.modal.tsx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/layouts/bookmark/components/modal/edit-bookmark.modal.tsx b/src/layouts/bookmark/components/modal/edit-bookmark.modal.tsx index d26e2f6e..dfb38174 100644 --- a/src/layouts/bookmark/components/modal/edit-bookmark.modal.tsx +++ b/src/layouts/bookmark/components/modal/edit-bookmark.modal.tsx @@ -35,6 +35,7 @@ export function EditBookmarkModal({ customTextColor: '', sticker: '', touched: false, + password: '', }) const [iconSource, setIconSource] = useState('auto') @@ -64,6 +65,7 @@ export function EditBookmarkModal({ customTextColor: bookmark.customTextColor || '', sticker: bookmark.sticker || '', touched: false, + password: bookmark.password, }) setIconSource(bookmark.customImage ? 'upload' : 'auto') @@ -101,6 +103,7 @@ export function EditBookmarkModal({ customBackground: formData.customBackground || undefined, customTextColor: formData.customTextColor || undefined, sticker: formData.sticker || undefined, + password: formData.password || undefined, } if (type === 'BOOKMARK') { @@ -190,6 +193,21 @@ export function EditBookmarkModal({ } /> + {type === 'FOLDER' && ( +
+ updateFormData('password', v)} + className={ + 'mt-2 w-full px-4 py-3 text-right absolute rounded-lg transition-all duration-300' + } + /> +
+ )} +
{type === 'BOOKMARK' && (