diff --git a/components/CollectionCard.tsx b/components/CollectionCard.tsx index 7ac8371..d68df69 100644 --- a/components/CollectionCard.tsx +++ b/components/CollectionCard.tsx @@ -1,5 +1,5 @@ import Link from "next/link"; -import { CollectionIncludingMembersAndLinkCount } from "@/types/global"; +import { AccountSettings, CollectionIncludingMembersAndLinkCount } from "@/types/global"; import React, { useEffect, useState } from "react"; import ProfilePhoto from "./ProfilePhoto"; import usePermissions from "@/hooks/usePermissions"; @@ -33,15 +33,7 @@ export default function CollectionCard({ collection, className }: Props) { const permissions = usePermissions(collection.id as number); - const [collectionOwner, setCollectionOwner] = useState({ - id: null as unknown as number, - name: "", - username: "", - image: "", - archiveAsScreenshot: undefined as unknown as boolean, - archiveAsMonolith: undefined as unknown as boolean, - archiveAsPDF: undefined as unknown as boolean, - }); + const [collectionOwner, setCollectionOwner] = useState>({}); useEffect(() => { const fetchOwner = async () => { diff --git a/components/InputSelect/CollectionSelection.tsx b/components/InputSelect/CollectionSelection.tsx index 6354f7e..31caa03 100644 --- a/components/InputSelect/CollectionSelection.tsx +++ b/components/InputSelect/CollectionSelection.tsx @@ -6,16 +6,6 @@ import { Options } from "./types"; import CreatableSelect from "react-select/creatable"; import Select, { ActionMeta } from "react-select"; -interface Option { - label: string; - value: number; - ownerId: number; - count?: { - links: number; - }; - parentId?: number; -} - type Props = { onChange: (newValue: unknown, actionMeta: ActionMeta) => void; showDefaultValue?: boolean; @@ -113,7 +103,7 @@ export default function CollectionSelection({ onChange={onChange} options={options} styles={styles} - defaultValue={showDefaultValue ? defaultValue : null} + defaultValue={showDefaultValue && defaultValue} components={{ Option: customOption, }} @@ -129,7 +119,7 @@ export default function CollectionSelection({ onChange={onChange} options={options} styles={styles} - defaultValue={showDefaultValue ? defaultValue : null} + defaultValue={showDefaultValue && defaultValue} components={{ Option: customOption, }} diff --git a/components/InputSelect/TagSelection.tsx b/components/InputSelect/TagSelection.tsx index 104e92b..e33cd3a 100644 --- a/components/InputSelect/TagSelection.tsx +++ b/components/InputSelect/TagSelection.tsx @@ -35,7 +35,6 @@ export default function TagSelection({ onChange, defaultValue }: Props) { options={options} styles={styles} defaultValue={defaultValue} - // menuPosition="fixed" isMulti /> ); diff --git a/components/ModalContent/EditCollectionSharingModal.tsx b/components/ModalContent/EditCollectionSharingModal.tsx index 9a9f5fa..76f0a47 100644 --- a/components/ModalContent/EditCollectionSharingModal.tsx +++ b/components/ModalContent/EditCollectionSharingModal.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react"; import TextInput from "@/components/TextInput"; import useCollectionStore from "@/store/collections"; import toast from "react-hot-toast"; -import { CollectionIncludingMembersAndLinkCount, Member } from "@/types/global"; +import { AccountSettings, CollectionIncludingMembersAndLinkCount, Member } from "@/types/global"; import getPublicUserData from "@/lib/client/getPublicUserData"; import useAccountStore from "@/store/account"; import usePermissions from "@/hooks/usePermissions"; @@ -62,15 +62,7 @@ export default function EditCollectionSharingModal({ const [memberUsername, setMemberUsername] = useState(""); - const [collectionOwner, setCollectionOwner] = useState({ - id: null as unknown as number, - name: "", - username: "", - image: "", - archiveAsScreenshot: undefined as unknown as boolean, - archiveAsMonolith: undefined as unknown as boolean, - archiveAsPDF: undefined as unknown as boolean, - }); + const [collectionOwner, setCollectionOwner] = useState>({}); useEffect(() => { const fetchOwner = async () => { @@ -130,7 +122,7 @@ export default function EditCollectionSharingModal({ )} - {collection.isPublic ? ( + {collection.isPublic && (

{t("sharable_link_guide")}

- ) : null} + )} {permissions === true &&
} diff --git a/components/ModalContent/PreservedFormatsModal.tsx b/components/ModalContent/PreservedFormatsModal.tsx index 58a71ba..c70f8c0 100644 --- a/components/ModalContent/PreservedFormatsModal.tsx +++ b/components/ModalContent/PreservedFormatsModal.tsx @@ -3,6 +3,7 @@ import useLinkStore from "@/store/links"; import { LinkIncludingShortenedCollectionAndTags, ArchivedFormat, + AccountSettings, } from "@/types/global"; import toast from "react-hot-toast"; import Link from "next/link"; @@ -37,15 +38,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) { let isPublic = router.pathname.startsWith("/public") ? true : undefined; - const [collectionOwner, setCollectionOwner] = useState({ - id: null as unknown as number, - name: "", - username: "", - image: "", - archiveAsScreenshot: undefined as unknown as boolean, - archiveAsMonolith: undefined as unknown as boolean, - archiveAsPDF: undefined as unknown as boolean, - }); + const [collectionOwner, setCollectionOwner] = useState>({}); useEffect(() => { const fetchOwner = async () => { diff --git a/lib/api/controllers/dashboard/getDashboardData.ts b/lib/api/controllers/dashboard/getDashboardData.ts index 8e19ae3..5324fde 100644 --- a/lib/api/controllers/dashboard/getDashboardData.ts +++ b/lib/api/controllers/dashboard/getDashboardData.ts @@ -71,7 +71,7 @@ export default async function getDashboardData( }); const links = [...recentlyAddedLinks, ...pinnedLinks].sort( - (a, b) => (new Date(b.id) as any) - (new Date(a.id) as any) + (a, b) => new Date(b.id).getTime() - new Date(a.id).getTime() ); return { response: links, status: 200 }; diff --git a/lib/api/controllers/dashboard/getDashboardDataV2.ts b/lib/api/controllers/dashboard/getDashboardDataV2.ts index ef58be4..11e1303 100644 --- a/lib/api/controllers/dashboard/getDashboardDataV2.ts +++ b/lib/api/controllers/dashboard/getDashboardDataV2.ts @@ -105,9 +105,8 @@ export default async function getDashboardData( }); const links = [...recentlyAddedLinks, ...pinnedLinks].sort( - (a, b) => (new Date(b.id) as any) - (new Date(a.id) as any) + (a, b) => new Date(b.id).getTime() - new Date(a.id).getTime() ); - return { data: { links, diff --git a/lib/api/controllers/session/createSession.ts b/lib/api/controllers/session/createSession.ts index c1a6aa7..178c42d 100644 --- a/lib/api/controllers/session/createSession.ts +++ b/lib/api/controllers/session/createSession.ts @@ -29,7 +29,7 @@ export default async function createSession( secret: process.env.NEXTAUTH_SECRET as string, }); - const createToken = await prisma.accessToken.create({ + await prisma.accessToken.create({ data: { name: sessionName || "Unknown Device", userId, diff --git a/lib/api/controllers/users/userId/deleteUserById.ts b/lib/api/controllers/users/userId/deleteUserById.ts index a6e6106..af3eb88 100644 --- a/lib/api/controllers/users/userId/deleteUserById.ts +++ b/lib/api/controllers/users/userId/deleteUserById.ts @@ -26,7 +26,7 @@ export default async function deleteUserById( if (user.password) { const isPasswordValid = bcrypt.compareSync( body.password, - user.password as string + user.password ); if (!isPasswordValid && !isServerAdmin) { diff --git a/lib/client/resizeImage.ts b/lib/client/resizeImage.ts index 17cbe56..f229c48 100644 --- a/lib/client/resizeImage.ts +++ b/lib/client/resizeImage.ts @@ -9,7 +9,7 @@ export const resizeImage = (file: File): Promise => "JPEG", // output format 100, // quality 0, // rotation - (uri: any) => { + (uri) => { resolve(uri as Blob); }, "blob" // output type diff --git a/pages/api/v1/archives/[linkId].ts b/pages/api/v1/archives/[linkId].ts index aed8288..bd7e856 100644 --- a/pages/api/v1/archives/[linkId].ts +++ b/pages/api/v1/archives/[linkId].ts @@ -166,8 +166,12 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) { where: { id: linkId }, }); - if (linkStillExists && files.file[0].mimetype?.includes("image")) { - const collectionId = collectionPermissions.id as number; + const { mimetype } = files.file[0]; + const isPDF = mimetype?.includes("pdf"); + const isImage = mimetype?.includes("image"); + + if (linkStillExists && isImage) { + const collectionId = collectionPermissions.id; createFolder({ filePath: `archives/preview/${collectionId}`, }); @@ -184,15 +188,9 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) { await prisma.link.update({ where: { id: linkId }, data: { - preview: files.file[0].mimetype?.includes("pdf") - ? "unavailable" - : undefined, - image: files.file[0].mimetype?.includes("image") - ? `archives/${collectionPermissions.id}/${linkId + suffix}` - : null, - pdf: files.file[0].mimetype?.includes("pdf") - ? `archives/${collectionPermissions.id}/${linkId + suffix}` - : null, + preview: isPDF ? "unavailable" : undefined, + image: isImage ? `archives/${collectionPermissions.id}/${linkId + suffix}` : null, + pdf: isPDF ? `archives/${collectionPermissions.id}/${linkId + suffix}` : null, lastPreserved: new Date().toISOString(), }, }); diff --git a/pages/collections/[id].tsx b/pages/collections/[id].tsx index c014aeb..ed0fa38 100644 --- a/pages/collections/[id].tsx +++ b/pages/collections/[id].tsx @@ -1,6 +1,7 @@ import useCollectionStore from "@/store/collections"; import useLinkStore from "@/store/links"; import { + AccountSettings, CollectionIncludingMembersAndLinkCount, Sort, ViewMode, @@ -53,15 +54,7 @@ export default function Index() { const { account } = useAccountStore(); - const [collectionOwner, setCollectionOwner] = useState({ - id: null as unknown as number, - name: "", - username: "", - image: "", - archiveAsScreenshot: undefined as unknown as boolean, - archiveAsMonolith: undefined as unknown as boolean, - archiveAsPDF: undefined as unknown as boolean, - }); + const [collectionOwner, setCollectionOwner] = useState>({}); useEffect(() => { const fetchOwner = async () => { @@ -217,7 +210,7 @@ export default function Index() { /> )} {activeCollection.members - .sort((a, b) => (a.userId as number) - (b.userId as number)) + .sort((a, b) => (a.userId) - (b.userId)) .map((e, i) => { return ( >({}); const [searchFilter, setSearchFilter] = useState({ name: true, diff --git a/pages/settings/account.tsx b/pages/settings/account.tsx index 2ba80fa..0484214 100644 --- a/pages/settings/account.tsx +++ b/pages/settings/account.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from "react"; +import { useState, useEffect, ChangeEvent } from "react"; import useAccountStore from "@/store/account"; import { AccountSettings } from "@/types/global"; import { toast } from "react-hot-toast"; @@ -54,8 +54,10 @@ export default function Account() { if (!objectIsEmpty(account)) setUser({ ...account }); }, [account]); - const handleImageUpload = async (e: any) => { - const file: File = e.target.files[0]; + const handleImageUpload = async (e: ChangeEvent) => { + const file = e.target.files?.[0]; + if (!file) return toast.error(t("image_upload_no_file_error")); + const fileExtension = file.name.split(".").pop()?.toLowerCase(); const allowedExtensions = ["png", "jpeg", "jpg"]; if (allowedExtensions.includes(fileExtension as string)) { @@ -100,9 +102,10 @@ export default function Account() { setSubmitLoader(false); }; - const importBookmarks = async (e: any, format: MigrationFormat) => { + const importBookmarks = async (e: ChangeEvent, format: MigrationFormat) => { setSubmitLoader(true); - const file: File = e.target.files[0]; + const file = e.target.files?.[0]; + if (file) { var reader = new FileReader(); reader.readAsText(file, "UTF-8"); diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 868fac0..a0588c0 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -117,6 +117,7 @@ "applying_settings": "Applying settings...", "settings_applied": "Settings Applied!", "email_change_request": "Email change request sent. Please verify the new email address.", + "image_upload_no_file_error": "No file selected. Please choose an image to upload.", "image_upload_size_error": "Please select a PNG or JPEG file that's less than 1MB.", "image_upload_format_error": "Invalid file format.", "importing_bookmarks": "Importing bookmarks...", diff --git a/public/locales/it/common.json b/public/locales/it/common.json index 5a76d83..e3ae533 100644 --- a/public/locales/it/common.json +++ b/public/locales/it/common.json @@ -117,6 +117,7 @@ "applying_settings": "Applicazione delle impostazioni in corso...", "settings_applied": "Impostazioni Applicate!", "email_change_request": "Richiesta di cambio email inviata. Per favore verifica il nuovo indirizzo email.", + "image_upload_no_file_error": "Nessun file selezionato. Scegli un'immagine da caricare.", "image_upload_size_error": "Per favore seleziona un file PNG o JPEG di dimensioni inferiori a 1MB.", "image_upload_format_error": "Formato file non valido.", "importing_bookmarks": "Importazione dei segnalibri in corso...", @@ -367,4 +368,4 @@ "server_administration": "Amministrazione Server", "all_collections": "Tutte le Collezioni", "dashboard": "Dashboard" -} +} \ No newline at end of file