mirror of
https://github.com/kyantech/Palmr.git
synced 2025-10-23 06:11:58 +00:00
feat: enhance reverse share functionality with QR code support
- Added QR code viewing and downloading capabilities in the reverse shares section. - Updated UI components to include QR code options in share details and cards. - Introduced new state management for handling QR code visibility. - Enhanced translations for QR code interactions across multiple languages.
This commit is contained in:
@@ -355,6 +355,12 @@
|
|||||||
"stats": "{iconCount} أيقونة من {libraryCount} مكتبة",
|
"stats": "{iconCount} أيقونة من {libraryCount} مكتبة",
|
||||||
"categoryBadge": "{category} ({count} أيقونات)"
|
"categoryBadge": "{category} ({count} أيقونات)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "تعديل الصورة",
|
||||||
|
"rotate": "تدوير",
|
||||||
|
"zoom": "تكبير/تصغير",
|
||||||
|
"cropInstructions": "اسحب لإعادة تحديد الموضع، غير حجم الزوايا لضبط منطقة القص"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "مرحبا بك",
|
"welcome": "مرحبا بك",
|
||||||
"signInToContinue": "قم بتسجيل الدخول للمتابعة",
|
"signInToContinue": "قم بتسجيل الدخول للمتابعة",
|
||||||
@@ -1721,11 +1727,5 @@
|
|||||||
"passwordRequired": "كلمة المرور مطلوبة",
|
"passwordRequired": "كلمة المرور مطلوبة",
|
||||||
"nameRequired": "الاسم مطلوب",
|
"nameRequired": "الاسم مطلوب",
|
||||||
"required": "هذا الحقل مطلوب"
|
"required": "هذا الحقل مطلوب"
|
||||||
},
|
|
||||||
"imageEdit": {
|
|
||||||
"title": "تعديل الصورة",
|
|
||||||
"rotate": "تدوير",
|
|
||||||
"zoom": "تكبير/تصغير",
|
|
||||||
"cropInstructions": "اسحب لإعادة تحديد الموضع، غير حجم الزوايا لضبط منطقة القص"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -355,6 +355,12 @@
|
|||||||
"stats": "{iconCount} Symbole aus {libraryCount} Bibliotheken",
|
"stats": "{iconCount} Symbole aus {libraryCount} Bibliotheken",
|
||||||
"categoryBadge": "{category} ({count} Symbole)"
|
"categoryBadge": "{category} ({count} Symbole)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "Bild bearbeiten",
|
||||||
|
"rotate": "Drehen",
|
||||||
|
"zoom": "Zoom",
|
||||||
|
"cropInstructions": "Ziehen Sie, um die Position zu ändern, ändern Sie die Größe der Ecken, um die Zuschneidefläche anzupassen"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "Willkommen zu",
|
"welcome": "Willkommen zu",
|
||||||
"signInToContinue": "Melden Sie sich an, um fortzufahren",
|
"signInToContinue": "Melden Sie sich an, um fortzufahren",
|
||||||
@@ -1719,11 +1725,5 @@
|
|||||||
"passwordRequired": "Passwort ist erforderlich",
|
"passwordRequired": "Passwort ist erforderlich",
|
||||||
"nameRequired": "Name ist erforderlich",
|
"nameRequired": "Name ist erforderlich",
|
||||||
"required": "Dieses Feld ist erforderlich"
|
"required": "Dieses Feld ist erforderlich"
|
||||||
},
|
|
||||||
"imageEdit": {
|
|
||||||
"title": "Bild bearbeiten",
|
|
||||||
"rotate": "Drehen",
|
|
||||||
"zoom": "Zoom",
|
|
||||||
"cropInstructions": "Ziehen Sie, um die Position zu ändern, ändern Sie die Größe der Ecken, um die Zuschneidefläche anzupassen"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -360,6 +360,12 @@
|
|||||||
"stats": "{iconCount} icons from {libraryCount} libraries",
|
"stats": "{iconCount} icons from {libraryCount} libraries",
|
||||||
"categoryBadge": "{category} ({count} icons)"
|
"categoryBadge": "{category} ({count} icons)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "Edit Image",
|
||||||
|
"rotate": "Rotate",
|
||||||
|
"zoom": "Zoom",
|
||||||
|
"cropInstructions": "Drag to reposition, resize corners to adjust crop area"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "Welcome to",
|
"welcome": "Welcome to",
|
||||||
"signInToContinue": "Sign in to continue",
|
"signInToContinue": "Sign in to continue",
|
||||||
@@ -405,12 +411,6 @@
|
|||||||
"navigation": {
|
"navigation": {
|
||||||
"dashboard": "Dashboard"
|
"dashboard": "Dashboard"
|
||||||
},
|
},
|
||||||
"imageEdit": {
|
|
||||||
"title": "Edit Image",
|
|
||||||
"rotate": "Rotate",
|
|
||||||
"zoom": "Zoom",
|
|
||||||
"cropInstructions": "Drag to reposition, resize corners to adjust crop area"
|
|
||||||
},
|
|
||||||
"profile": {
|
"profile": {
|
||||||
"password": {
|
"password": {
|
||||||
"title": "Change Password",
|
"title": "Change Password",
|
||||||
@@ -453,6 +453,11 @@
|
|||||||
},
|
},
|
||||||
"pageTitle": "Profile"
|
"pageTitle": "Profile"
|
||||||
},
|
},
|
||||||
|
"qrCodeModal": {
|
||||||
|
"title": "Share QR Code",
|
||||||
|
"description": "Scan this QR code to access the link.",
|
||||||
|
"download": "Download QR Code"
|
||||||
|
},
|
||||||
"quickAccess": {
|
"quickAccess": {
|
||||||
"files": {
|
"files": {
|
||||||
"title": "My Files",
|
"title": "My Files",
|
||||||
@@ -618,6 +623,7 @@
|
|||||||
"expired": "Expired",
|
"expired": "Expired",
|
||||||
"expires": "Expires",
|
"expires": "Expires",
|
||||||
"viewDetails": "View details",
|
"viewDetails": "View details",
|
||||||
|
"viewQrCode": "View QR Code",
|
||||||
"copyLink": "Copy Link",
|
"copyLink": "Copy Link",
|
||||||
"openInNewTab": "Open in New Tab",
|
"openInNewTab": "Open in New Tab",
|
||||||
"editLink": "Edit Link",
|
"editLink": "Edit Link",
|
||||||
@@ -640,7 +646,8 @@
|
|||||||
"viewDetails": "View Details",
|
"viewDetails": "View Details",
|
||||||
"edit": "Edit",
|
"edit": "Edit",
|
||||||
"delete": "Delete",
|
"delete": "Delete",
|
||||||
"viewFiles": "Received Files"
|
"viewFiles": "Received Files",
|
||||||
|
"viewQrCode": "View QR Code"
|
||||||
},
|
},
|
||||||
"empty": {
|
"empty": {
|
||||||
"title": "No receive links created",
|
"title": "No receive links created",
|
||||||
@@ -1461,11 +1468,6 @@
|
|||||||
"dark": "Dark",
|
"dark": "Dark",
|
||||||
"system": "System"
|
"system": "System"
|
||||||
},
|
},
|
||||||
"qrCodeModal": {
|
|
||||||
"title": "Share QR Code",
|
|
||||||
"description": "Scan this QR code to access the shared files.",
|
|
||||||
"download": "Download QR Code"
|
|
||||||
},
|
|
||||||
"twoFactor": {
|
"twoFactor": {
|
||||||
"title": "Two-Factor Authentication",
|
"title": "Two-Factor Authentication",
|
||||||
"description": "Add an extra layer of security to your account",
|
"description": "Add an extra layer of security to your account",
|
||||||
|
@@ -355,6 +355,12 @@
|
|||||||
"stats": "{iconCount} iconos de {libraryCount} bibliotecas",
|
"stats": "{iconCount} iconos de {libraryCount} bibliotecas",
|
||||||
"categoryBadge": "{category} ({count} iconos)"
|
"categoryBadge": "{category} ({count} iconos)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "Editar Imagen",
|
||||||
|
"rotate": "Rotar",
|
||||||
|
"zoom": "Zoom",
|
||||||
|
"cropInstructions": "Arrastra para reubicar, ajusta las esquinas para ajustar el área de recorte"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "Bienvenido a",
|
"welcome": "Bienvenido a",
|
||||||
"signInToContinue": "Inicia sesión para continuar",
|
"signInToContinue": "Inicia sesión para continuar",
|
||||||
@@ -1719,11 +1725,5 @@
|
|||||||
"passwordRequired": "Se requiere la contraseña",
|
"passwordRequired": "Se requiere la contraseña",
|
||||||
"nameRequired": "El nombre es obligatorio",
|
"nameRequired": "El nombre es obligatorio",
|
||||||
"required": "Este campo es obligatorio"
|
"required": "Este campo es obligatorio"
|
||||||
},
|
|
||||||
"imageEdit": {
|
|
||||||
"title": "Editar Imagen",
|
|
||||||
"rotate": "Rotar",
|
|
||||||
"zoom": "Zoom",
|
|
||||||
"cropInstructions": "Arrastra para reubicar, ajusta las esquinas para ajustar el área de recorte"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -355,6 +355,12 @@
|
|||||||
"stats": "{iconCount} icônes de {libraryCount} bibliothèques",
|
"stats": "{iconCount} icônes de {libraryCount} bibliothèques",
|
||||||
"categoryBadge": "{category} ({count} icônes)"
|
"categoryBadge": "{category} ({count} icônes)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "Modifier l'Image",
|
||||||
|
"rotate": "Tourner",
|
||||||
|
"zoom": "Zoom",
|
||||||
|
"cropInstructions": "Glisser pour répositionner, redimensionner les coins pour ajuster la zone de découpe"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "Bienvenue à",
|
"welcome": "Bienvenue à",
|
||||||
"signInToContinue": "Connectez-vous pour continuer",
|
"signInToContinue": "Connectez-vous pour continuer",
|
||||||
@@ -1719,11 +1725,5 @@
|
|||||||
"passwordRequired": "Le mot de passe est requis",
|
"passwordRequired": "Le mot de passe est requis",
|
||||||
"nameRequired": "Nome é obrigatório",
|
"nameRequired": "Nome é obrigatório",
|
||||||
"required": "Este campo é obrigatório"
|
"required": "Este campo é obrigatório"
|
||||||
},
|
|
||||||
"imageEdit": {
|
|
||||||
"title": "Modifier l'Image",
|
|
||||||
"rotate": "Tourner",
|
|
||||||
"zoom": "Zoom",
|
|
||||||
"cropInstructions": "Glisser pour répositionner, redimensionner les coins pour ajuster la zone de découpe"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -355,6 +355,12 @@
|
|||||||
"stats": "{libraryCount} लाइब्रेरी से {iconCount} आइकन",
|
"stats": "{libraryCount} लाइब्रेरी से {iconCount} आइकन",
|
||||||
"categoryBadge": "{category} ({count} आइकन)"
|
"categoryBadge": "{category} ({count} आइकन)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "छवि संपादित करें",
|
||||||
|
"rotate": "घुमाएं",
|
||||||
|
"zoom": "ज़ूम",
|
||||||
|
"cropInstructions": "छवि को पुनः स्थानांतरित करने के लिए खींचें, कोणों को समायोजित करने के लिए आकार बदलें"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "स्वागत है में",
|
"welcome": "स्वागत है में",
|
||||||
"signInToContinue": "जारी रखने के लिए साइन इन करें",
|
"signInToContinue": "जारी रखने के लिए साइन इन करें",
|
||||||
@@ -1719,11 +1725,5 @@
|
|||||||
"passwordRequired": "पासवर्ड आवश्यक है",
|
"passwordRequired": "पासवर्ड आवश्यक है",
|
||||||
"nameRequired": "नाम आवश्यक है",
|
"nameRequired": "नाम आवश्यक है",
|
||||||
"required": "यह फ़ील्ड आवश्यक है"
|
"required": "यह फ़ील्ड आवश्यक है"
|
||||||
},
|
|
||||||
"imageEdit": {
|
|
||||||
"title": "छवि संपादित करें",
|
|
||||||
"rotate": "घुमाएं",
|
|
||||||
"zoom": "ज़ूम",
|
|
||||||
"cropInstructions": "छवि को पुनः स्थानांतरित करने के लिए खींचें, कोणों को समायोजित करने के लिए आकार बदलें"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -355,6 +355,12 @@
|
|||||||
"stats": "{iconCount} icone da {libraryCount} librerie",
|
"stats": "{iconCount} icone da {libraryCount} librerie",
|
||||||
"categoryBadge": "{category} ({count} icone)"
|
"categoryBadge": "{category} ({count} icone)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "Modifica Immagine",
|
||||||
|
"rotate": "Ruota",
|
||||||
|
"zoom": "Zoom",
|
||||||
|
"cropInstructions": "Trascina per riposizionare, ridimensiona gli angoli per adattare l'area di ritaglio"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "Benvenuto in",
|
"welcome": "Benvenuto in",
|
||||||
"signInToContinue": "Accedi per continuare",
|
"signInToContinue": "Accedi per continuare",
|
||||||
@@ -1719,11 +1725,5 @@
|
|||||||
"passwordMinLength": "La password deve contenere almeno 6 caratteri",
|
"passwordMinLength": "La password deve contenere almeno 6 caratteri",
|
||||||
"nameRequired": "Il nome è obbligatorio",
|
"nameRequired": "Il nome è obbligatorio",
|
||||||
"required": "Questo campo è obbligatorio"
|
"required": "Questo campo è obbligatorio"
|
||||||
},
|
|
||||||
"imageEdit": {
|
|
||||||
"title": "Modifica Immagine",
|
|
||||||
"rotate": "Ruota",
|
|
||||||
"zoom": "Zoom",
|
|
||||||
"cropInstructions": "Trascina per riposizionare, ridimensiona gli angoli per adattare l'area di ritaglio"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -355,6 +355,12 @@
|
|||||||
"stats": "{libraryCount}ライブラリから{iconCount}個のアイコン",
|
"stats": "{libraryCount}ライブラリから{iconCount}個のアイコン",
|
||||||
"categoryBadge": "{category}({count}個のアイコン)"
|
"categoryBadge": "{category}({count}個のアイコン)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "画像を編集",
|
||||||
|
"rotate": "回転",
|
||||||
|
"zoom": "ズーム",
|
||||||
|
"cropInstructions": "位置を変更するにはドラッグし、カット領域を調整するには角をリサイズしてください"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "ようこそへ",
|
"welcome": "ようこそへ",
|
||||||
"signInToContinue": "続行するにはサインインしてください",
|
"signInToContinue": "続行するにはサインインしてください",
|
||||||
@@ -1719,11 +1725,5 @@
|
|||||||
"passwordRequired": "パスワードは必須です",
|
"passwordRequired": "パスワードは必須です",
|
||||||
"nameRequired": "名前は必須です",
|
"nameRequired": "名前は必須です",
|
||||||
"required": "このフィールドは必須です"
|
"required": "このフィールドは必須です"
|
||||||
},
|
|
||||||
"imageEdit": {
|
|
||||||
"title": "画像を編集",
|
|
||||||
"rotate": "回転",
|
|
||||||
"zoom": "ズーム",
|
|
||||||
"cropInstructions": "位置を変更するにはドラッグし、カット領域を調整するには角をリサイズしてください"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -355,6 +355,12 @@
|
|||||||
"stats": "{libraryCount}개의 라이브러리에서 {iconCount}개의 아이콘",
|
"stats": "{libraryCount}개의 라이브러리에서 {iconCount}개의 아이콘",
|
||||||
"categoryBadge": "{category} ({count}개의 아이콘)"
|
"categoryBadge": "{category} ({count}개의 아이콘)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "이미지 편집",
|
||||||
|
"rotate": "회전",
|
||||||
|
"zoom": "확대/축소",
|
||||||
|
"cropInstructions": "위치를 변경하려면 드래그하고, 자르기 영역을 조정하려면 모서리를 확대/축소하세요"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "에 오신 것을 환영합니다",
|
"welcome": "에 오신 것을 환영합니다",
|
||||||
"signInToContinue": "계속하려면 로그인하세요",
|
"signInToContinue": "계속하려면 로그인하세요",
|
||||||
@@ -1719,11 +1725,5 @@
|
|||||||
"passwordRequired": "비밀번호는 필수입니다",
|
"passwordRequired": "비밀번호는 필수입니다",
|
||||||
"nameRequired": "이름은 필수입니다",
|
"nameRequired": "이름은 필수입니다",
|
||||||
"required": "이 필드는 필수입니다"
|
"required": "이 필드는 필수입니다"
|
||||||
},
|
|
||||||
"imageEdit": {
|
|
||||||
"title": "이미지 편집",
|
|
||||||
"rotate": "회전",
|
|
||||||
"zoom": "확대/축소",
|
|
||||||
"cropInstructions": "위치를 변경하려면 드래그하고, 자르기 영역을 조정하려면 모서리를 확대/축소하세요"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -355,6 +355,12 @@
|
|||||||
"stats": "{iconCount} pictogrammen van {libraryCount} bibliotheken",
|
"stats": "{iconCount} pictogrammen van {libraryCount} bibliotheken",
|
||||||
"categoryBadge": "{category} ({count} pictogrammen)"
|
"categoryBadge": "{category} ({count} pictogrammen)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "Afbeelding bewerken",
|
||||||
|
"rotate": "Draai",
|
||||||
|
"zoom": "Vergroot",
|
||||||
|
"cropInstructions": "Sleep om te herpositioneren, verander de grootte van de hoeken om de uitsnijdgebied aan te passen"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "Welkom bij",
|
"welcome": "Welkom bij",
|
||||||
"signInToContinue": "Log in om door te gaan",
|
"signInToContinue": "Log in om door te gaan",
|
||||||
@@ -1719,11 +1725,5 @@
|
|||||||
"passwordMinLength": "Wachtwoord moet minimaal 6 tekens bevatten",
|
"passwordMinLength": "Wachtwoord moet minimaal 6 tekens bevatten",
|
||||||
"nameRequired": "Naam is verplicht",
|
"nameRequired": "Naam is verplicht",
|
||||||
"required": "Dit veld is verplicht"
|
"required": "Dit veld is verplicht"
|
||||||
},
|
|
||||||
"imageEdit": {
|
|
||||||
"title": "Afbeelding bewerken",
|
|
||||||
"rotate": "Draai",
|
|
||||||
"zoom": "Vergroot",
|
|
||||||
"cropInstructions": "Sleep om te herpositioneren, verander de grootte van de hoeken om de uitsnijdgebied aan te passen"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -355,6 +355,12 @@
|
|||||||
"stats": "{iconCount} ikon z {libraryCount} bibliotek",
|
"stats": "{iconCount} ikon z {libraryCount} bibliotek",
|
||||||
"categoryBadge": "{category} ({count} ikon)"
|
"categoryBadge": "{category} ({count} ikon)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "Edytuj obraz",
|
||||||
|
"rotate": "Obróć",
|
||||||
|
"zoom": "Powiększ",
|
||||||
|
"cropInstructions": "Przeciągnij, aby przesunąć, zmień rozmiar rogów, aby dostosować obszar przycięcia"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "Witaj w",
|
"welcome": "Witaj w",
|
||||||
"signInToContinue": "Zaloguj się, aby kontynuować",
|
"signInToContinue": "Zaloguj się, aby kontynuować",
|
||||||
@@ -1719,11 +1725,5 @@
|
|||||||
"passwordMinLength": "Hasło musi mieć co najmniej 6 znaków",
|
"passwordMinLength": "Hasło musi mieć co najmniej 6 znaków",
|
||||||
"nameRequired": "Nazwa jest wymagana",
|
"nameRequired": "Nazwa jest wymagana",
|
||||||
"required": "To pole jest wymagane"
|
"required": "To pole jest wymagane"
|
||||||
},
|
|
||||||
"imageEdit": {
|
|
||||||
"title": "Edytuj obraz",
|
|
||||||
"rotate": "Obróć",
|
|
||||||
"zoom": "Powiększ",
|
|
||||||
"cropInstructions": "Przeciągnij, aby przesunąć, zmień rozmiar rogów, aby dostosować obszar przycięcia"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -355,6 +355,12 @@
|
|||||||
"stats": "{iconCount} ícones de {libraryCount} bibliotecas",
|
"stats": "{iconCount} ícones de {libraryCount} bibliotecas",
|
||||||
"categoryBadge": "{category} ({count} ícones)"
|
"categoryBadge": "{category} ({count} ícones)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "Editar imagem",
|
||||||
|
"rotate": "Girar",
|
||||||
|
"zoom": "Ampliar",
|
||||||
|
"cropInstructions": "Arraste para reposicionar, redimensione os cantos para ajustar a área de recorte"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "Bem-vindo ao",
|
"welcome": "Bem-vindo ao",
|
||||||
"signInToContinue": "Faça login para continuar",
|
"signInToContinue": "Faça login para continuar",
|
||||||
@@ -1719,11 +1725,5 @@
|
|||||||
"lastNameRequired": "O sobrenome é necessário",
|
"lastNameRequired": "O sobrenome é necessário",
|
||||||
"usernameLength": "O nome de usuário deve ter pelo menos 3 caracteres",
|
"usernameLength": "O nome de usuário deve ter pelo menos 3 caracteres",
|
||||||
"usernameSpaces": "O nome de usuário não pode conter espaços"
|
"usernameSpaces": "O nome de usuário não pode conter espaços"
|
||||||
},
|
|
||||||
"imageEdit": {
|
|
||||||
"title": "Editar imagem",
|
|
||||||
"rotate": "Girar",
|
|
||||||
"zoom": "Ampliar",
|
|
||||||
"cropInstructions": "Arraste para reposicionar, redimensione os cantos para ajustar a área de recorte"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -355,6 +355,12 @@
|
|||||||
"stats": "{iconCount} иконок из {libraryCount} библиотек",
|
"stats": "{iconCount} иконок из {libraryCount} библиотек",
|
||||||
"categoryBadge": "{category} ({count} иконок)"
|
"categoryBadge": "{category} ({count} иконок)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "Редактировать изображение",
|
||||||
|
"rotate": "Повернуть",
|
||||||
|
"zoom": "Увеличить",
|
||||||
|
"cropInstructions": "Перетащите, чтобы переместить, измените размер углов, чтобы отрегулировать область обрезки"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "Добро пожаловать в",
|
"welcome": "Добро пожаловать в",
|
||||||
"signInToContinue": "Войдите, чтобы продолжить",
|
"signInToContinue": "Войдите, чтобы продолжить",
|
||||||
@@ -1719,11 +1725,5 @@
|
|||||||
"passwordRequired": "Требуется пароль",
|
"passwordRequired": "Требуется пароль",
|
||||||
"nameRequired": "Требуется имя",
|
"nameRequired": "Требуется имя",
|
||||||
"required": "Это поле обязательно"
|
"required": "Это поле обязательно"
|
||||||
},
|
|
||||||
"imageEdit": {
|
|
||||||
"title": "Редактировать изображение",
|
|
||||||
"rotate": "Повернуть",
|
|
||||||
"zoom": "Увеличить",
|
|
||||||
"cropInstructions": "Перетащите, чтобы переместить, измените размер углов, чтобы отрегулировать область обрезки"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -355,6 +355,12 @@
|
|||||||
"stats": "{libraryCount} kütüphaneden {iconCount} simge",
|
"stats": "{libraryCount} kütüphaneden {iconCount} simge",
|
||||||
"categoryBadge": "{category} ({count} simge)"
|
"categoryBadge": "{category} ({count} simge)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "Resmi Düzenle",
|
||||||
|
"rotate": "Döndür",
|
||||||
|
"zoom": "Yakınlaştır",
|
||||||
|
"cropInstructions": "Yerleştirmek için sürükleyin, kırpma alanını ayarlamak için köşeleri yeniden boyutlandırın"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "Hoş geldiniz'e",
|
"welcome": "Hoş geldiniz'e",
|
||||||
"signInToContinue": "Devam etmek için oturum açın",
|
"signInToContinue": "Devam etmek için oturum açın",
|
||||||
@@ -1719,11 +1725,5 @@
|
|||||||
"passwordRequired": "Şifre gerekli",
|
"passwordRequired": "Şifre gerekli",
|
||||||
"nameRequired": "İsim gereklidir",
|
"nameRequired": "İsim gereklidir",
|
||||||
"required": "Bu alan zorunludur"
|
"required": "Bu alan zorunludur"
|
||||||
},
|
|
||||||
"imageEdit": {
|
|
||||||
"title": "Resmi Düzenle",
|
|
||||||
"rotate": "Döndür",
|
|
||||||
"zoom": "Yakınlaştır",
|
|
||||||
"cropInstructions": "Yerleştirmek için sürükleyin, kırpma alanını ayarlamak için köşeleri yeniden boyutlandırın"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -355,6 +355,12 @@
|
|||||||
"stats": "来自 {libraryCount} 个库的 {iconCount} 个图标",
|
"stats": "来自 {libraryCount} 个库的 {iconCount} 个图标",
|
||||||
"categoryBadge": "{category}({count} 个图标)"
|
"categoryBadge": "{category}({count} 个图标)"
|
||||||
},
|
},
|
||||||
|
"imageEdit": {
|
||||||
|
"title": "编辑图片",
|
||||||
|
"rotate": "旋转",
|
||||||
|
"zoom": "缩放",
|
||||||
|
"cropInstructions": "拖动以重新定位,调整角落大小以调整裁剪区域"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"welcome": "欢迎您",
|
"welcome": "欢迎您",
|
||||||
"signInToContinue": "请登录以继续",
|
"signInToContinue": "请登录以继续",
|
||||||
@@ -1483,11 +1489,7 @@
|
|||||||
"copyToClipboard": "复制到剪贴板",
|
"copyToClipboard": "复制到剪贴板",
|
||||||
"savedMessage": "我已保存备用码",
|
"savedMessage": "我已保存备用码",
|
||||||
"available": "可用备用码:{count}个",
|
"available": "可用备用码:{count}个",
|
||||||
"instructions": [
|
"instructions": ["• 将这些代码保存在安全的位置", "• 每个备用码只能使用一次", "• 您可以随时生成新的备用码"]
|
||||||
"• 将这些代码保存在安全的位置",
|
|
||||||
"• 每个备用码只能使用一次",
|
|
||||||
"• 您可以随时生成新的备用码"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
"title": "双重认证",
|
"title": "双重认证",
|
||||||
@@ -1719,11 +1721,5 @@
|
|||||||
"passwordRequired": "密码为必填项",
|
"passwordRequired": "密码为必填项",
|
||||||
"nameRequired": "名称为必填项",
|
"nameRequired": "名称为必填项",
|
||||||
"required": "此字段为必填项"
|
"required": "此字段为必填项"
|
||||||
},
|
|
||||||
"imageEdit": {
|
|
||||||
"title": "编辑图片",
|
|
||||||
"rotate": "旋转",
|
|
||||||
"zoom": "缩放",
|
|
||||||
"cropInstructions": "拖动以重新定位,调整角落大小以调整裁剪区域"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -11,6 +11,7 @@ import {
|
|||||||
IconLink,
|
IconLink,
|
||||||
IconLock,
|
IconLock,
|
||||||
IconLockOpen,
|
IconLockOpen,
|
||||||
|
IconQrcode,
|
||||||
IconToggleLeft,
|
IconToggleLeft,
|
||||||
IconToggleRight,
|
IconToggleRight,
|
||||||
IconTrash,
|
IconTrash,
|
||||||
@@ -38,6 +39,7 @@ interface ReverseShareCardProps {
|
|||||||
onGenerateLink: (reverseShare: ReverseShare) => void;
|
onGenerateLink: (reverseShare: ReverseShare) => void;
|
||||||
onViewDetails: (reverseShare: ReverseShare) => void;
|
onViewDetails: (reverseShare: ReverseShare) => void;
|
||||||
onViewFiles: (reverseShare: ReverseShare) => void;
|
onViewFiles: (reverseShare: ReverseShare) => void;
|
||||||
|
onViewQrCode?: (reverseShare: ReverseShare) => void;
|
||||||
onUpdateReverseShare?: (id: string, data: any) => Promise<any>;
|
onUpdateReverseShare?: (id: string, data: any) => Promise<any>;
|
||||||
onToggleActive?: (id: string, isActive: boolean) => Promise<any>;
|
onToggleActive?: (id: string, isActive: boolean) => Promise<any>;
|
||||||
onUpdatePassword?: (id: string, data: { hasPassword: boolean; password?: string }) => Promise<any>;
|
onUpdatePassword?: (id: string, data: { hasPassword: boolean; password?: string }) => Promise<any>;
|
||||||
@@ -51,6 +53,7 @@ export function ReverseShareCard({
|
|||||||
onGenerateLink,
|
onGenerateLink,
|
||||||
onViewDetails,
|
onViewDetails,
|
||||||
onViewFiles,
|
onViewFiles,
|
||||||
|
onViewQrCode,
|
||||||
onUpdateReverseShare,
|
onUpdateReverseShare,
|
||||||
onToggleActive,
|
onToggleActive,
|
||||||
onUpdatePassword,
|
onUpdatePassword,
|
||||||
@@ -230,6 +233,18 @@ export function ReverseShareCard({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
|
{hasAlias && onViewQrCode && (
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className="h-6 w-6 p-0 hover:bg-background/80 rounded-sm"
|
||||||
|
onClick={() => onViewQrCode(reverseShare)}
|
||||||
|
title={t("reverseShares.card.viewQrCode")}
|
||||||
|
>
|
||||||
|
<IconQrcode className="h-3 w-3" />
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -239,7 +254,6 @@ export function ReverseShareCard({
|
|||||||
>
|
>
|
||||||
<IconEye className="h-3 w-3" />
|
<IconEye className="h-3 w-3" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -257,6 +271,11 @@ export function ReverseShareCard({
|
|||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="end">
|
<DropdownMenuContent align="end">
|
||||||
|
<DropdownMenuItem onClick={() => onViewDetails(reverseShare)}>
|
||||||
|
<IconEye className="h-4 w-4" />
|
||||||
|
{t("reverseShares.card.viewDetails")}
|
||||||
|
</DropdownMenuItem>
|
||||||
|
|
||||||
<DropdownMenuItem onClick={() => onCopyLink(reverseShare)}>
|
<DropdownMenuItem onClick={() => onCopyLink(reverseShare)}>
|
||||||
<IconCopy className="h-4 w-4" />
|
<IconCopy className="h-4 w-4" />
|
||||||
{t("reverseShares.card.copyLink")}
|
{t("reverseShares.card.copyLink")}
|
||||||
@@ -286,6 +305,13 @@ export function ReverseShareCard({
|
|||||||
{t("reverseShares.actions.viewFiles")}
|
{t("reverseShares.actions.viewFiles")}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
|
||||||
|
{hasAlias && onViewQrCode && (
|
||||||
|
<DropdownMenuItem onClick={() => onViewQrCode(reverseShare)}>
|
||||||
|
<IconQrcode className="h-4 w-4" />
|
||||||
|
{t("reverseShares.actions.viewQrCode")}
|
||||||
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
|
|
||||||
<DropdownMenuItem className="text-destructive" onClick={() => onDelete(reverseShare)}>
|
<DropdownMenuItem className="text-destructive" onClick={() => onDelete(reverseShare)}>
|
||||||
<IconTrash className="h-4 w-4" />
|
<IconTrash className="h-4 w-4" />
|
||||||
{t("reverseShares.card.delete")}
|
{t("reverseShares.card.delete")}
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
IconCopy,
|
IconCopy,
|
||||||
|
IconDownload,
|
||||||
IconEdit,
|
IconEdit,
|
||||||
IconLink,
|
IconLink,
|
||||||
IconLock,
|
IconLock,
|
||||||
@@ -11,6 +12,7 @@ import {
|
|||||||
IconToggleRight,
|
IconToggleRight,
|
||||||
} from "@tabler/icons-react";
|
} from "@tabler/icons-react";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
import QRCode from "react-qr-code";
|
||||||
|
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
@@ -42,6 +44,7 @@ interface ReverseShareDetailsModalProps {
|
|||||||
onCopyLink?: (reverseShare: ReverseShare) => void;
|
onCopyLink?: (reverseShare: ReverseShare) => void;
|
||||||
onToggleActive?: (id: string, isActive: boolean) => Promise<void>;
|
onToggleActive?: (id: string, isActive: boolean) => Promise<void>;
|
||||||
onUpdatePassword?: (id: string, data: { hasPassword: boolean; password?: string }) => Promise<void>;
|
onUpdatePassword?: (id: string, data: { hasPassword: boolean; password?: string }) => Promise<void>;
|
||||||
|
onViewQrCode?: (reverseShare: ReverseShare) => void;
|
||||||
refreshTrigger?: number;
|
refreshTrigger?: number;
|
||||||
onSuccess?: () => void;
|
onSuccess?: () => void;
|
||||||
}
|
}
|
||||||
@@ -55,10 +58,12 @@ export function ReverseShareDetailsModal({
|
|||||||
onCopyLink,
|
onCopyLink,
|
||||||
onToggleActive,
|
onToggleActive,
|
||||||
onUpdatePassword,
|
onUpdatePassword,
|
||||||
|
onViewQrCode,
|
||||||
onSuccess,
|
onSuccess,
|
||||||
}: ReverseShareDetailsModalProps) {
|
}: ReverseShareDetailsModalProps) {
|
||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
const [pendingChanges, setPendingChanges] = useState<Record<string, any>>({});
|
const [pendingChanges, setPendingChanges] = useState<Record<string, any>>({});
|
||||||
|
const [isDownloading, setIsDownloading] = useState(false);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
showAliasModal,
|
showAliasModal,
|
||||||
@@ -140,6 +145,7 @@ export function ReverseShareDetailsModal({
|
|||||||
isActive={reverseShare.isActive}
|
isActive={reverseShare.isActive}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
{/* Informações Básicas */}
|
{/* Informações Básicas */}
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<h3 className="text-base font-medium text-foreground border-b pb-2">
|
<h3 className="text-base font-medium text-foreground border-b pb-2">
|
||||||
@@ -182,6 +188,78 @@ export function ReverseShareDetailsModal({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* QR Code */}
|
||||||
|
{reverseShareLink && (
|
||||||
|
<div className="space-y-3">
|
||||||
|
<div className="flex items-center gap-2 border-b pb-2">
|
||||||
|
<h3
|
||||||
|
className="text-base font-medium text-foreground cursor-pointer"
|
||||||
|
onClick={() => onViewQrCode && onViewQrCode(reverseShare)}
|
||||||
|
>
|
||||||
|
{t("qrCodeModal.title")}
|
||||||
|
</h3>
|
||||||
|
<Button
|
||||||
|
size="icon"
|
||||||
|
variant="ghost"
|
||||||
|
className="h-5 w-5 text-muted-foreground hover:text-foreground"
|
||||||
|
onClick={() => {
|
||||||
|
const svg = document.getElementById("reverse-share-details-qr-code");
|
||||||
|
if (!svg) return;
|
||||||
|
|
||||||
|
setIsDownloading(true);
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
const padding = 20;
|
||||||
|
canvas.width = 200 + padding * 2;
|
||||||
|
canvas.height = 200 + padding * 2;
|
||||||
|
|
||||||
|
if (ctx) {
|
||||||
|
ctx.fillStyle = "#FFFFFF";
|
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
const svgData = new XMLSerializer().serializeToString(svg);
|
||||||
|
const img = new Image();
|
||||||
|
|
||||||
|
img.onload = () => {
|
||||||
|
ctx.drawImage(img, padding, padding, 200, 200);
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.download = `${reverseShare?.name?.replace(/[^a-z0-9]/gi, "-").toLowerCase() || "reverse-share"}-qr-code.png`;
|
||||||
|
link.href = canvas.toDataURL("image/png");
|
||||||
|
link.click();
|
||||||
|
setIsDownloading(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
img.src = `data:image/svg+xml;base64,${btoa(svgData)}`;
|
||||||
|
} else {
|
||||||
|
setIsDownloading(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
disabled={isDownloading}
|
||||||
|
title={t("qrCodeModal.download")}
|
||||||
|
>
|
||||||
|
<IconDownload className="h-3 w-3" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col items-start justify-start">
|
||||||
|
<div
|
||||||
|
className="p-2 bg-white rounded-lg cursor-pointer hover:opacity-80 transition-opacity duration-300"
|
||||||
|
onClick={() => onViewQrCode && onViewQrCode(reverseShare)}
|
||||||
|
title={t("reverseShares.actions.viewQrCode")}
|
||||||
|
>
|
||||||
|
<QRCode
|
||||||
|
id="reverse-share-details-qr-code"
|
||||||
|
value={reverseShareLink}
|
||||||
|
size={100}
|
||||||
|
level="H"
|
||||||
|
fgColor="#000000"
|
||||||
|
bgColor="#FFFFFF"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Link de Compartilhamento */}
|
{/* Link de Compartilhamento */}
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="flex items-center gap-2 border-b pb-2">
|
<div className="flex items-center gap-2 border-b pb-2">
|
||||||
|
@@ -10,6 +10,7 @@ interface ReverseSharesCardsContainerProps {
|
|||||||
onGenerateLink: (reverseShare: ReverseShare) => void;
|
onGenerateLink: (reverseShare: ReverseShare) => void;
|
||||||
onViewDetails: (reverseShare: ReverseShare) => void;
|
onViewDetails: (reverseShare: ReverseShare) => void;
|
||||||
onViewFiles: (reverseShare: ReverseShare) => void;
|
onViewFiles: (reverseShare: ReverseShare) => void;
|
||||||
|
onViewQrCode?: (reverseShare: ReverseShare) => void;
|
||||||
onCreateReverseShare: () => void;
|
onCreateReverseShare: () => void;
|
||||||
onUpdateReverseShare?: (id: string, data: any) => Promise<any>;
|
onUpdateReverseShare?: (id: string, data: any) => Promise<any>;
|
||||||
onToggleActive?: (id: string, isActive: boolean) => Promise<any>;
|
onToggleActive?: (id: string, isActive: boolean) => Promise<any>;
|
||||||
@@ -24,6 +25,7 @@ export function ReverseSharesCardsContainer({
|
|||||||
onGenerateLink,
|
onGenerateLink,
|
||||||
onViewDetails,
|
onViewDetails,
|
||||||
onViewFiles,
|
onViewFiles,
|
||||||
|
onViewQrCode,
|
||||||
onCreateReverseShare,
|
onCreateReverseShare,
|
||||||
onUpdateReverseShare,
|
onUpdateReverseShare,
|
||||||
onToggleActive,
|
onToggleActive,
|
||||||
@@ -45,6 +47,7 @@ export function ReverseSharesCardsContainer({
|
|||||||
onGenerateLink={onGenerateLink}
|
onGenerateLink={onGenerateLink}
|
||||||
onViewDetails={onViewDetails}
|
onViewDetails={onViewDetails}
|
||||||
onViewFiles={onViewFiles}
|
onViewFiles={onViewFiles}
|
||||||
|
onViewQrCode={onViewQrCode}
|
||||||
onUpdateReverseShare={onUpdateReverseShare}
|
onUpdateReverseShare={onUpdateReverseShare}
|
||||||
onToggleActive={onToggleActive}
|
onToggleActive={onToggleActive}
|
||||||
onUpdatePassword={onUpdatePassword}
|
onUpdatePassword={onUpdatePassword}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import { QrCodeModal } from "@/components/modals/qr-code-modal";
|
||||||
import type { CreateReverseShareBody, UpdateReverseShareBody } from "@/http/endpoints/reverse-shares/types";
|
import type { CreateReverseShareBody, UpdateReverseShareBody } from "@/http/endpoints/reverse-shares/types";
|
||||||
import { ReverseShare } from "../hooks/use-reverse-shares";
|
import { ReverseShare } from "../hooks/use-reverse-shares";
|
||||||
import { CreateReverseShareModal } from "./create-reverse-share-modal";
|
import { CreateReverseShareModal } from "./create-reverse-share-modal";
|
||||||
@@ -20,14 +21,17 @@ interface ReverseSharesModalsProps {
|
|||||||
reverseShareToGenerateLink: ReverseShare | null;
|
reverseShareToGenerateLink: ReverseShare | null;
|
||||||
reverseShareToDelete: ReverseShare | null;
|
reverseShareToDelete: ReverseShare | null;
|
||||||
reverseShareToViewFiles: ReverseShare | null;
|
reverseShareToViewFiles: ReverseShare | null;
|
||||||
|
reverseShareToViewQrCode: ReverseShare | null;
|
||||||
isDeleting: boolean;
|
isDeleting: boolean;
|
||||||
onCloseViewDetails: () => void;
|
onCloseViewDetails: () => void;
|
||||||
onCloseGenerateLink: () => void;
|
onCloseGenerateLink: () => void;
|
||||||
onCloseDeleteModal: () => void;
|
onCloseDeleteModal: () => void;
|
||||||
onCloseViewFiles: () => void;
|
onCloseViewFiles: () => void;
|
||||||
|
onCloseViewQrCode: () => void;
|
||||||
onConfirmDelete: (reverseShare: ReverseShare) => Promise<void>;
|
onConfirmDelete: (reverseShare: ReverseShare) => Promise<void>;
|
||||||
onCreateAlias: (reverseShareId: string, alias: string) => Promise<void>;
|
onCreateAlias: (reverseShareId: string, alias: string) => Promise<void>;
|
||||||
onCopyLink: (reverseShare: ReverseShare) => void;
|
onCopyLink: (reverseShare: ReverseShare) => void;
|
||||||
|
onViewQrCode: (reverseShare: ReverseShare) => void;
|
||||||
onUpdateReverseShareData?: (id: string, data: any) => Promise<any>;
|
onUpdateReverseShareData?: (id: string, data: any) => Promise<any>;
|
||||||
onUpdatePassword?: (id: string, data: { hasPassword: boolean; password?: string }) => Promise<any>;
|
onUpdatePassword?: (id: string, data: { hasPassword: boolean; password?: string }) => Promise<any>;
|
||||||
onToggleActive?: (id: string, isActive: boolean) => Promise<any>;
|
onToggleActive?: (id: string, isActive: boolean) => Promise<any>;
|
||||||
@@ -48,14 +52,17 @@ export function ReverseSharesModals({
|
|||||||
reverseShareToGenerateLink,
|
reverseShareToGenerateLink,
|
||||||
reverseShareToDelete,
|
reverseShareToDelete,
|
||||||
reverseShareToViewFiles,
|
reverseShareToViewFiles,
|
||||||
|
reverseShareToViewQrCode,
|
||||||
isDeleting,
|
isDeleting,
|
||||||
onCloseViewDetails,
|
onCloseViewDetails,
|
||||||
onCloseGenerateLink,
|
onCloseGenerateLink,
|
||||||
onCloseDeleteModal,
|
onCloseDeleteModal,
|
||||||
onCloseViewFiles,
|
onCloseViewFiles,
|
||||||
|
onCloseViewQrCode,
|
||||||
onConfirmDelete,
|
onConfirmDelete,
|
||||||
onCreateAlias,
|
onCreateAlias,
|
||||||
onCopyLink,
|
onCopyLink,
|
||||||
|
onViewQrCode,
|
||||||
onUpdateReverseShareData,
|
onUpdateReverseShareData,
|
||||||
onUpdatePassword,
|
onUpdatePassword,
|
||||||
onToggleActive,
|
onToggleActive,
|
||||||
@@ -103,6 +110,7 @@ export function ReverseSharesModals({
|
|||||||
onCopyLink={onCopyLink}
|
onCopyLink={onCopyLink}
|
||||||
onUpdatePassword={onUpdatePassword}
|
onUpdatePassword={onUpdatePassword}
|
||||||
onToggleActive={onToggleActive}
|
onToggleActive={onToggleActive}
|
||||||
|
onViewQrCode={onViewQrCode}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ReceivedFilesModal
|
<ReceivedFilesModal
|
||||||
@@ -112,6 +120,17 @@ export function ReverseSharesModals({
|
|||||||
onRefresh={onRefreshData}
|
onRefresh={onRefreshData}
|
||||||
refreshReverseShare={refreshReverseShare}
|
refreshReverseShare={refreshReverseShare}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<QrCodeModal
|
||||||
|
isOpen={!!reverseShareToViewQrCode}
|
||||||
|
onClose={onCloseViewQrCode}
|
||||||
|
shareLink={
|
||||||
|
reverseShareToViewQrCode?.alias?.alias
|
||||||
|
? `${typeof window !== "undefined" ? window.location.origin : ""}/r/${reverseShareToViewQrCode.alias.alias}`
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
shareName={reverseShareToViewQrCode?.name || "Reverse Share"}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,7 @@ export function useReverseShares() {
|
|||||||
const [reverseShareToDelete, setReverseShareToDelete] = useState<ReverseShare | null>(null);
|
const [reverseShareToDelete, setReverseShareToDelete] = useState<ReverseShare | null>(null);
|
||||||
const [reverseShareToEdit, setReverseShareToEdit] = useState<ReverseShare | null>(null);
|
const [reverseShareToEdit, setReverseShareToEdit] = useState<ReverseShare | null>(null);
|
||||||
const [reverseShareToViewFiles, setReverseShareToViewFiles] = useState<ReverseShare | null>(null);
|
const [reverseShareToViewFiles, setReverseShareToViewFiles] = useState<ReverseShare | null>(null);
|
||||||
|
const [reverseShareToViewQrCode, setReverseShareToViewQrCode] = useState<ReverseShare | null>(null);
|
||||||
const [isDeleting, setIsDeleting] = useState(false);
|
const [isDeleting, setIsDeleting] = useState(false);
|
||||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
||||||
const [isCreating, setIsCreating] = useState(false);
|
const [isCreating, setIsCreating] = useState(false);
|
||||||
@@ -277,6 +278,7 @@ export function useReverseShares() {
|
|||||||
reverseShareToDelete,
|
reverseShareToDelete,
|
||||||
reverseShareToEdit,
|
reverseShareToEdit,
|
||||||
reverseShareToViewFiles,
|
reverseShareToViewFiles,
|
||||||
|
reverseShareToViewQrCode,
|
||||||
isDeleting,
|
isDeleting,
|
||||||
isCreateModalOpen,
|
isCreateModalOpen,
|
||||||
isCreating,
|
isCreating,
|
||||||
@@ -288,6 +290,7 @@ export function useReverseShares() {
|
|||||||
setReverseShareToDelete,
|
setReverseShareToDelete,
|
||||||
setReverseShareToEdit,
|
setReverseShareToEdit,
|
||||||
setReverseShareToViewFiles,
|
setReverseShareToViewFiles,
|
||||||
|
setReverseShareToViewQrCode,
|
||||||
setIsCreateModalOpen,
|
setIsCreateModalOpen,
|
||||||
handleCopyLink,
|
handleCopyLink,
|
||||||
handleDeleteReverseShare,
|
handleDeleteReverseShare,
|
||||||
|
@@ -23,6 +23,7 @@ export default function ReverseSharesPage() {
|
|||||||
reverseShareToDelete,
|
reverseShareToDelete,
|
||||||
reverseShareToEdit,
|
reverseShareToEdit,
|
||||||
reverseShareToViewFiles,
|
reverseShareToViewFiles,
|
||||||
|
reverseShareToViewQrCode,
|
||||||
isDeleting,
|
isDeleting,
|
||||||
isCreateModalOpen,
|
isCreateModalOpen,
|
||||||
isCreating,
|
isCreating,
|
||||||
@@ -37,6 +38,7 @@ export default function ReverseSharesPage() {
|
|||||||
setReverseShareToDelete,
|
setReverseShareToDelete,
|
||||||
setReverseShareToEdit,
|
setReverseShareToEdit,
|
||||||
setReverseShareToViewFiles,
|
setReverseShareToViewFiles,
|
||||||
|
setReverseShareToViewQrCode,
|
||||||
handleCreateAlias,
|
handleCreateAlias,
|
||||||
handleUpdatePassword,
|
handleUpdatePassword,
|
||||||
handleUpdateReverseShareData,
|
handleUpdateReverseShareData,
|
||||||
@@ -77,6 +79,7 @@ export default function ReverseSharesPage() {
|
|||||||
onGenerateLink={setReverseShareToGenerateLink}
|
onGenerateLink={setReverseShareToGenerateLink}
|
||||||
onViewDetails={setReverseShareToViewDetails}
|
onViewDetails={setReverseShareToViewDetails}
|
||||||
onViewFiles={setReverseShareToViewFiles}
|
onViewFiles={setReverseShareToViewFiles}
|
||||||
|
onViewQrCode={setReverseShareToViewQrCode}
|
||||||
onCreateReverseShare={() => setIsCreateModalOpen(true)}
|
onCreateReverseShare={() => setIsCreateModalOpen(true)}
|
||||||
onUpdateReverseShare={handleUpdateReverseShareData}
|
onUpdateReverseShare={handleUpdateReverseShareData}
|
||||||
onToggleActive={handleToggleActive}
|
onToggleActive={handleToggleActive}
|
||||||
@@ -99,14 +102,17 @@ export default function ReverseSharesPage() {
|
|||||||
reverseShareToViewDetails={reverseShareToViewDetails}
|
reverseShareToViewDetails={reverseShareToViewDetails}
|
||||||
reverseShareToDelete={reverseShareToDelete}
|
reverseShareToDelete={reverseShareToDelete}
|
||||||
reverseShareToViewFiles={reverseShareToViewFiles}
|
reverseShareToViewFiles={reverseShareToViewFiles}
|
||||||
|
reverseShareToViewQrCode={reverseShareToViewQrCode}
|
||||||
isDeleting={isDeleting}
|
isDeleting={isDeleting}
|
||||||
onCloseGenerateLink={() => setReverseShareToGenerateLink(null)}
|
onCloseGenerateLink={() => setReverseShareToGenerateLink(null)}
|
||||||
onCloseViewDetails={() => setReverseShareToViewDetails(null)}
|
onCloseViewDetails={() => setReverseShareToViewDetails(null)}
|
||||||
onCloseDeleteModal={() => setReverseShareToDelete(null)}
|
onCloseDeleteModal={() => setReverseShareToDelete(null)}
|
||||||
onCloseViewFiles={() => setReverseShareToViewFiles(null)}
|
onCloseViewFiles={() => setReverseShareToViewFiles(null)}
|
||||||
|
onCloseViewQrCode={() => setReverseShareToViewQrCode(null)}
|
||||||
onConfirmDelete={handleDeleteReverseShare}
|
onConfirmDelete={handleDeleteReverseShare}
|
||||||
onCreateAlias={handleCreateAlias}
|
onCreateAlias={handleCreateAlias}
|
||||||
onCopyLink={handleCopyLink}
|
onCopyLink={handleCopyLink}
|
||||||
|
onViewQrCode={setReverseShareToViewQrCode}
|
||||||
onUpdateReverseShareData={handleUpdateReverseShareData}
|
onUpdateReverseShareData={handleUpdateReverseShareData}
|
||||||
onUpdatePassword={handleUpdatePassword}
|
onUpdatePassword={handleUpdatePassword}
|
||||||
onToggleActive={handleToggleActive}
|
onToggleActive={handleToggleActive}
|
||||||
|
@@ -173,8 +173,8 @@ export function GenerateShareLinkModal({
|
|||||||
|
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button onClick={downloadQRCode} disabled={isDownloading}>
|
<Button onClick={downloadQRCode} disabled={isDownloading}>
|
||||||
<IconDownload className="h-4 w-4 mr-2" />
|
<IconDownload className="h-4 w-4" />
|
||||||
{t("qrCodeModal.download", { defaultValue: "Download QR Code" })}
|
{t("qrCodeModal.download")}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -93,7 +93,7 @@ export function QrCodeModal({ isOpen, onClose, shareLink, shareName }: QrCodeMod
|
|||||||
{t("common.close")}
|
{t("common.close")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={downloadQRCode} className="mt-2 sm:mt-0" disabled={isDownloading}>
|
<Button onClick={downloadQRCode} className="mt-2 sm:mt-0" disabled={isDownloading}>
|
||||||
<IconDownload className="h-4 w-4 mr-2" />
|
<IconDownload className="h-4 w-4" />
|
||||||
{t("qrCodeModal.download", { defaultValue: "Download QR Code" })}
|
{t("qrCodeModal.download", { defaultValue: "Download QR Code" })}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
@@ -1,11 +1,7 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2017",
|
"target": "ES2017",
|
||||||
"lib": [
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
"dom",
|
|
||||||
"dom.iterable",
|
|
||||||
"esnext"
|
|
||||||
],
|
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
@@ -23,20 +19,9 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": [
|
"@/*": ["./src/*"]
|
||||||
"./src/*"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": ["node_modules", ".next/types/app/api/(proxy)/**/*", ".next/types/**/*.ts"],
|
||||||
"node_modules",
|
"include": ["**/*.ts", "**/*.tsx", "next-env.d.ts", ".next/types/**/*.ts"]
|
||||||
".next/types/app/api/(proxy)/**/*",
|
|
||||||
".next/types/**/*.ts"
|
|
||||||
],
|
|
||||||
"include": [
|
|
||||||
"**/*.ts",
|
|
||||||
"**/*.tsx",
|
|
||||||
"next-env.d.ts",
|
|
||||||
".next/types/**/*.ts"
|
|
||||||
]
|
|
||||||
}
|
}
|
Reference in New Issue
Block a user