Fix more types and use logical ANDs
This commit is contained in:
parent
ff31732ba3
commit
4faf389a2b
|
@ -1,5 +1,5 @@
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
|
import { AccountSettings, CollectionIncludingMembersAndLinkCount } from "@/types/global";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import ProfilePhoto from "./ProfilePhoto";
|
import ProfilePhoto from "./ProfilePhoto";
|
||||||
import usePermissions from "@/hooks/usePermissions";
|
import usePermissions from "@/hooks/usePermissions";
|
||||||
|
@ -33,15 +33,7 @@ export default function CollectionCard({ collection, className }: Props) {
|
||||||
|
|
||||||
const permissions = usePermissions(collection.id as number);
|
const permissions = usePermissions(collection.id as number);
|
||||||
|
|
||||||
const [collectionOwner, setCollectionOwner] = useState({
|
const [collectionOwner, setCollectionOwner] = useState<Partial<AccountSettings>>({});
|
||||||
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,
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchOwner = async () => {
|
const fetchOwner = async () => {
|
||||||
|
|
|
@ -6,16 +6,6 @@ import { Options } from "./types";
|
||||||
import CreatableSelect from "react-select/creatable";
|
import CreatableSelect from "react-select/creatable";
|
||||||
import Select, { ActionMeta } from "react-select";
|
import Select, { ActionMeta } from "react-select";
|
||||||
|
|
||||||
interface Option {
|
|
||||||
label: string;
|
|
||||||
value: number;
|
|
||||||
ownerId: number;
|
|
||||||
count?: {
|
|
||||||
links: number;
|
|
||||||
};
|
|
||||||
parentId?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
onChange: (newValue: unknown, actionMeta: ActionMeta<unknown>) => void;
|
onChange: (newValue: unknown, actionMeta: ActionMeta<unknown>) => void;
|
||||||
showDefaultValue?: boolean;
|
showDefaultValue?: boolean;
|
||||||
|
@ -113,7 +103,7 @@ export default function CollectionSelection({
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
options={options}
|
options={options}
|
||||||
styles={styles}
|
styles={styles}
|
||||||
defaultValue={showDefaultValue ? defaultValue : null}
|
defaultValue={showDefaultValue && defaultValue}
|
||||||
components={{
|
components={{
|
||||||
Option: customOption,
|
Option: customOption,
|
||||||
}}
|
}}
|
||||||
|
@ -129,7 +119,7 @@ export default function CollectionSelection({
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
options={options}
|
options={options}
|
||||||
styles={styles}
|
styles={styles}
|
||||||
defaultValue={showDefaultValue ? defaultValue : null}
|
defaultValue={showDefaultValue && defaultValue}
|
||||||
components={{
|
components={{
|
||||||
Option: customOption,
|
Option: customOption,
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -35,7 +35,6 @@ export default function TagSelection({ onChange, defaultValue }: Props) {
|
||||||
options={options}
|
options={options}
|
||||||
styles={styles}
|
styles={styles}
|
||||||
defaultValue={defaultValue}
|
defaultValue={defaultValue}
|
||||||
// menuPosition="fixed"
|
|
||||||
isMulti
|
isMulti
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
|
||||||
import TextInput from "@/components/TextInput";
|
import TextInput from "@/components/TextInput";
|
||||||
import useCollectionStore from "@/store/collections";
|
import useCollectionStore from "@/store/collections";
|
||||||
import toast from "react-hot-toast";
|
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 getPublicUserData from "@/lib/client/getPublicUserData";
|
||||||
import useAccountStore from "@/store/account";
|
import useAccountStore from "@/store/account";
|
||||||
import usePermissions from "@/hooks/usePermissions";
|
import usePermissions from "@/hooks/usePermissions";
|
||||||
|
@ -62,15 +62,7 @@ export default function EditCollectionSharingModal({
|
||||||
|
|
||||||
const [memberUsername, setMemberUsername] = useState("");
|
const [memberUsername, setMemberUsername] = useState("");
|
||||||
|
|
||||||
const [collectionOwner, setCollectionOwner] = useState({
|
const [collectionOwner, setCollectionOwner] = useState<Partial<AccountSettings>>({});
|
||||||
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,
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchOwner = async () => {
|
const fetchOwner = async () => {
|
||||||
|
@ -130,7 +122,7 @@ export default function EditCollectionSharingModal({
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{collection.isPublic ? (
|
{collection.isPublic && (
|
||||||
<div className={permissions === true ? "pl-5" : ""}>
|
<div className={permissions === true ? "pl-5" : ""}>
|
||||||
<p className="mb-2">{t("sharable_link_guide")}</p>
|
<p className="mb-2">{t("sharable_link_guide")}</p>
|
||||||
<div
|
<div
|
||||||
|
@ -148,7 +140,7 @@ export default function EditCollectionSharingModal({
|
||||||
{publicCollectionURL}
|
{publicCollectionURL}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
)}
|
||||||
|
|
||||||
{permissions === true && <div className="divider my-3"></div>}
|
{permissions === true && <div className="divider my-3"></div>}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import useLinkStore from "@/store/links";
|
||||||
import {
|
import {
|
||||||
LinkIncludingShortenedCollectionAndTags,
|
LinkIncludingShortenedCollectionAndTags,
|
||||||
ArchivedFormat,
|
ArchivedFormat,
|
||||||
|
AccountSettings,
|
||||||
} from "@/types/global";
|
} from "@/types/global";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
@ -37,15 +38,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
|
||||||
|
|
||||||
let isPublic = router.pathname.startsWith("/public") ? true : undefined;
|
let isPublic = router.pathname.startsWith("/public") ? true : undefined;
|
||||||
|
|
||||||
const [collectionOwner, setCollectionOwner] = useState({
|
const [collectionOwner, setCollectionOwner] = useState<Partial<AccountSettings>>({});
|
||||||
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,
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchOwner = async () => {
|
const fetchOwner = async () => {
|
||||||
|
|
|
@ -71,7 +71,7 @@ export default async function getDashboardData(
|
||||||
});
|
});
|
||||||
|
|
||||||
const links = [...recentlyAddedLinks, ...pinnedLinks].sort(
|
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 };
|
return { response: links, status: 200 };
|
||||||
|
|
|
@ -105,9 +105,8 @@ export default async function getDashboardData(
|
||||||
});
|
});
|
||||||
|
|
||||||
const links = [...recentlyAddedLinks, ...pinnedLinks].sort(
|
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 {
|
return {
|
||||||
data: {
|
data: {
|
||||||
links,
|
links,
|
||||||
|
|
|
@ -29,7 +29,7 @@ export default async function createSession(
|
||||||
secret: process.env.NEXTAUTH_SECRET as string,
|
secret: process.env.NEXTAUTH_SECRET as string,
|
||||||
});
|
});
|
||||||
|
|
||||||
const createToken = await prisma.accessToken.create({
|
await prisma.accessToken.create({
|
||||||
data: {
|
data: {
|
||||||
name: sessionName || "Unknown Device",
|
name: sessionName || "Unknown Device",
|
||||||
userId,
|
userId,
|
||||||
|
|
|
@ -26,7 +26,7 @@ export default async function deleteUserById(
|
||||||
if (user.password) {
|
if (user.password) {
|
||||||
const isPasswordValid = bcrypt.compareSync(
|
const isPasswordValid = bcrypt.compareSync(
|
||||||
body.password,
|
body.password,
|
||||||
user.password as string
|
user.password
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!isPasswordValid && !isServerAdmin) {
|
if (!isPasswordValid && !isServerAdmin) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ export const resizeImage = (file: File): Promise<Blob> =>
|
||||||
"JPEG", // output format
|
"JPEG", // output format
|
||||||
100, // quality
|
100, // quality
|
||||||
0, // rotation
|
0, // rotation
|
||||||
(uri: any) => {
|
(uri) => {
|
||||||
resolve(uri as Blob);
|
resolve(uri as Blob);
|
||||||
},
|
},
|
||||||
"blob" // output type
|
"blob" // output type
|
||||||
|
|
|
@ -166,8 +166,12 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) {
|
||||||
where: { id: linkId },
|
where: { id: linkId },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (linkStillExists && files.file[0].mimetype?.includes("image")) {
|
const { mimetype } = files.file[0];
|
||||||
const collectionId = collectionPermissions.id as number;
|
const isPDF = mimetype?.includes("pdf");
|
||||||
|
const isImage = mimetype?.includes("image");
|
||||||
|
|
||||||
|
if (linkStillExists && isImage) {
|
||||||
|
const collectionId = collectionPermissions.id;
|
||||||
createFolder({
|
createFolder({
|
||||||
filePath: `archives/preview/${collectionId}`,
|
filePath: `archives/preview/${collectionId}`,
|
||||||
});
|
});
|
||||||
|
@ -184,15 +188,9 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) {
|
||||||
await prisma.link.update({
|
await prisma.link.update({
|
||||||
where: { id: linkId },
|
where: { id: linkId },
|
||||||
data: {
|
data: {
|
||||||
preview: files.file[0].mimetype?.includes("pdf")
|
preview: isPDF ? "unavailable" : undefined,
|
||||||
? "unavailable"
|
image: isImage ? `archives/${collectionPermissions.id}/${linkId + suffix}` : null,
|
||||||
: undefined,
|
pdf: isPDF ? `archives/${collectionPermissions.id}/${linkId + suffix}` : null,
|
||||||
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,
|
|
||||||
lastPreserved: new Date().toISOString(),
|
lastPreserved: new Date().toISOString(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import useCollectionStore from "@/store/collections";
|
import useCollectionStore from "@/store/collections";
|
||||||
import useLinkStore from "@/store/links";
|
import useLinkStore from "@/store/links";
|
||||||
import {
|
import {
|
||||||
|
AccountSettings,
|
||||||
CollectionIncludingMembersAndLinkCount,
|
CollectionIncludingMembersAndLinkCount,
|
||||||
Sort,
|
Sort,
|
||||||
ViewMode,
|
ViewMode,
|
||||||
|
@ -53,15 +54,7 @@ export default function Index() {
|
||||||
|
|
||||||
const { account } = useAccountStore();
|
const { account } = useAccountStore();
|
||||||
|
|
||||||
const [collectionOwner, setCollectionOwner] = useState({
|
const [collectionOwner, setCollectionOwner] = useState<Partial<AccountSettings>>({});
|
||||||
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,
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchOwner = async () => {
|
const fetchOwner = async () => {
|
||||||
|
@ -217,7 +210,7 @@ export default function Index() {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{activeCollection.members
|
{activeCollection.members
|
||||||
.sort((a, b) => (a.userId as number) - (b.userId as number))
|
.sort((a, b) => (a.userId) - (b.userId))
|
||||||
.map((e, i) => {
|
.map((e, i) => {
|
||||||
return (
|
return (
|
||||||
<ProfilePhoto
|
<ProfilePhoto
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"use client";
|
"use client";
|
||||||
import getPublicCollectionData from "@/lib/client/getPublicCollectionData";
|
import getPublicCollectionData from "@/lib/client/getPublicCollectionData";
|
||||||
import {
|
import {
|
||||||
|
AccountSettings,
|
||||||
CollectionIncludingMembersAndLinkCount,
|
CollectionIncludingMembersAndLinkCount,
|
||||||
Sort,
|
Sort,
|
||||||
ViewMode,
|
ViewMode,
|
||||||
|
@ -36,15 +37,7 @@ export default function PublicCollections() {
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const [collectionOwner, setCollectionOwner] = useState({
|
const [collectionOwner, setCollectionOwner] = useState<Partial<AccountSettings>>({});
|
||||||
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 [searchFilter, setSearchFilter] = useState({
|
const [searchFilter, setSearchFilter] = useState({
|
||||||
name: true,
|
name: true,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect, ChangeEvent } from "react";
|
||||||
import useAccountStore from "@/store/account";
|
import useAccountStore from "@/store/account";
|
||||||
import { AccountSettings } from "@/types/global";
|
import { AccountSettings } from "@/types/global";
|
||||||
import { toast } from "react-hot-toast";
|
import { toast } from "react-hot-toast";
|
||||||
|
@ -54,8 +54,10 @@ export default function Account() {
|
||||||
if (!objectIsEmpty(account)) setUser({ ...account });
|
if (!objectIsEmpty(account)) setUser({ ...account });
|
||||||
}, [account]);
|
}, [account]);
|
||||||
|
|
||||||
const handleImageUpload = async (e: any) => {
|
const handleImageUpload = async (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
const file: File = e.target.files[0];
|
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 fileExtension = file.name.split(".").pop()?.toLowerCase();
|
||||||
const allowedExtensions = ["png", "jpeg", "jpg"];
|
const allowedExtensions = ["png", "jpeg", "jpg"];
|
||||||
if (allowedExtensions.includes(fileExtension as string)) {
|
if (allowedExtensions.includes(fileExtension as string)) {
|
||||||
|
@ -100,9 +102,10 @@ export default function Account() {
|
||||||
setSubmitLoader(false);
|
setSubmitLoader(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const importBookmarks = async (e: any, format: MigrationFormat) => {
|
const importBookmarks = async (e: ChangeEvent<HTMLInputElement>, format: MigrationFormat) => {
|
||||||
setSubmitLoader(true);
|
setSubmitLoader(true);
|
||||||
const file: File = e.target.files[0];
|
const file = e.target.files?.[0];
|
||||||
|
|
||||||
if (file) {
|
if (file) {
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
reader.readAsText(file, "UTF-8");
|
reader.readAsText(file, "UTF-8");
|
||||||
|
|
|
@ -117,6 +117,7 @@
|
||||||
"applying_settings": "Applying settings...",
|
"applying_settings": "Applying settings...",
|
||||||
"settings_applied": "Settings Applied!",
|
"settings_applied": "Settings Applied!",
|
||||||
"email_change_request": "Email change request sent. Please verify the new email address.",
|
"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_size_error": "Please select a PNG or JPEG file that's less than 1MB.",
|
||||||
"image_upload_format_error": "Invalid file format.",
|
"image_upload_format_error": "Invalid file format.",
|
||||||
"importing_bookmarks": "Importing bookmarks...",
|
"importing_bookmarks": "Importing bookmarks...",
|
||||||
|
|
|
@ -117,6 +117,7 @@
|
||||||
"applying_settings": "Applicazione delle impostazioni in corso...",
|
"applying_settings": "Applicazione delle impostazioni in corso...",
|
||||||
"settings_applied": "Impostazioni Applicate!",
|
"settings_applied": "Impostazioni Applicate!",
|
||||||
"email_change_request": "Richiesta di cambio email inviata. Per favore verifica il nuovo indirizzo email.",
|
"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_size_error": "Per favore seleziona un file PNG o JPEG di dimensioni inferiori a 1MB.",
|
||||||
"image_upload_format_error": "Formato file non valido.",
|
"image_upload_format_error": "Formato file non valido.",
|
||||||
"importing_bookmarks": "Importazione dei segnalibri in corso...",
|
"importing_bookmarks": "Importazione dei segnalibri in corso...",
|
||||||
|
@ -367,4 +368,4 @@
|
||||||
"server_administration": "Amministrazione Server",
|
"server_administration": "Amministrazione Server",
|
||||||
"all_collections": "Tutte le Collezioni",
|
"all_collections": "Tutte le Collezioni",
|
||||||
"dashboard": "Dashboard"
|
"dashboard": "Dashboard"
|
||||||
}
|
}
|
Ŝarĝante…
Reference in New Issue