diff --git a/src/layouts/bookmark/bookmarks.tsx b/src/layouts/bookmark/bookmarks.tsx index 69532844..e06ec168 100644 --- a/src/layouts/bookmark/bookmarks.tsx +++ b/src/layouts/bookmark/bookmarks.tsx @@ -11,6 +11,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 { @@ -24,19 +25,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) @@ -93,6 +92,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() @@ -110,13 +124,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) { @@ -315,7 +328,11 @@ export function BookmarksComponent() { bookmark ? (
{bookmark.type === 'FOLDER' ? (
+ { + 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 d0dded00..88cf258f 100644 --- a/src/layouts/bookmark/components/bookmark-folder.tsx +++ b/src/layouts/bookmark/components/bookmark-folder.tsx @@ -1,5 +1,6 @@ import { useState } from 'react' import { FaFolder, FaFolderOpen } from 'react-icons/fa' +import { LuFolderLock } from 'react-icons/lu' import { SlOptions } from 'react-icons/sl' import { addOpacityToColor } from '@/common/color' import Tooltip from '@/components/toolTip' @@ -37,7 +38,11 @@ export function FolderBookmarkItem({ const displayIcon = bookmark.customImage || (isHovered ? ( - + bookmark.password ? ( + + ) : ( + + ) ) : ( )) @@ -65,7 +70,11 @@ export function FolderBookmarkItem({ onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} style={customStyles} - className={`relative flex flex-col items-center justify-center p-4 transition-all duration-300 cursor-pointer group rounded-2xl w-full h-16 md:h-[5.5rem] shadow-sm ${!bookmark.customBackground ? getFolderStyle() : 'border hover:border-blue-400/40'} transition-all ease-in-out duration-300`} + className={`relative flex flex-col items-center justify-center p-4 transition-all duration-300 cursor-pointer group rounded-2xl w-full h-16 md:h-[5.5rem] shadow-sm ${ + !bookmark.customBackground + ? getFolderStyle() + : 'border hover:border-blue-400/40' + } transition-all ease-in-out duration-300`} > {RenderStickerPattern(bookmark)}
diff --git a/src/layouts/bookmark/components/modal/add-bookmark.modal.tsx b/src/layouts/bookmark/components/modal/add-bookmark.modal.tsx index 5a5e7df1..336f18e0 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://')) { @@ -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' && ( ('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' && ( void + onConfirm: () => void + folderPassword: string +} + +export function FolderPasswordModal({ + isOpen, + onClose, + onConfirm, + folderPassword, +}: FolderPasswordModalProps) { + const [password, setPassword] = useState('') + const [errorMessage, setErrorMessage] = useState('') + + const invalidPassword = 'رمز عبور اشتباه است. دوباره امتحان کنید' + + return ( + { + setPassword('') + setErrorMessage('') + onClose() + }} + > + +
+ setPassword(v)} + className={`mt-2 w-full px-4 py-3 text-right rounded-lg transition-all duration-300 ${errorMessage && 'border-error'}`} + /> + +
+ {errorMessage && ( +

+ {errorMessage} +

+ )} +
+ ) +} diff --git a/src/layouts/bookmark/components/shared.tsx b/src/layouts/bookmark/components/shared.tsx index 77573107..f11e3a60 100644 --- a/src/layouts/bookmark/components/shared.tsx +++ b/src/layouts/bookmark/components/shared.tsx @@ -16,6 +16,7 @@ export interface BookmarkFormData { customTextColor: string sticker: string touched?: boolean + password?: string } export function IconSourceSelector({ 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; }