Files
Stirling-PDF/frontend/src/core/components/shared/EncryptedPdfUnlockModal.tsx
T
James BruntonandGitHub 8ab060a4be Prettier 2: Electric Boogaloo (#6113)
# Description of Changes
When I added Prettier formatting in #6052, my aim was to use just the
default settings in Prettier. Turns out, Prettier looks _really hard_
for any config files if it's not explicitly given one, which means that
if a developer has some sort of Prettier config file lying around on
their system, Prettier might find it and use it. Also, Prettier changes
its defaults based on stuff in `.editorconfig` without any good way of
disabling that behaviour explicitly in its config file.

To solve both of these issues, I've introduced a `.prettierrc` file
which sets Prettier's defaults explicitly, and then reformatted all our
code _again_ in Prettier's actual default settings. This should achieve
the aim of #6052 and remove the possibility for it breaking on different
dev computers.
2026-04-17 09:50:16 +00:00

125 lines
3.3 KiB
TypeScript

import {
Modal,
Stack,
Text,
Button,
PasswordInput,
Group,
} from "@mantine/core";
import { useTranslation } from "react-i18next";
import { type KeyboardEventHandler } from "react";
import { Z_INDEX_OVER_FULLSCREEN_SURFACE } from "@app/styles/zIndex";
interface EncryptedPdfUnlockModalProps {
opened: boolean;
fileName?: string;
password: string;
errorMessage?: string | null;
isProcessing: boolean;
remainingCount: number;
onPasswordChange: (value: string) => void;
onUnlock: () => void;
onUnlockAll: () => void;
onSkip: () => void;
}
const EncryptedPdfUnlockModal = ({
opened,
fileName,
password,
errorMessage,
isProcessing,
remainingCount,
onPasswordChange,
onUnlock,
onUnlockAll,
onSkip,
}: EncryptedPdfUnlockModalProps) => {
const { t } = useTranslation();
const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = (event) => {
if (event.key === "Enter" && !isProcessing && password.trim().length > 0) {
onUnlock();
}
};
return (
<Modal
opened={opened}
onClose={onSkip}
title={t("encryptedPdfUnlock.title", "Remove password to continue")}
centered
size="md"
closeOnClickOutside={!isProcessing}
closeOnEscape={!isProcessing}
zIndex={Z_INDEX_OVER_FULLSCREEN_SURFACE}
>
<Stack gap="md">
<Text fw={600} ta="center">
{fileName}
</Text>
<Text c="dimmed" ta="center">
{t(
"encryptedPdfUnlock.description",
"This PDF is password protected. Enter the password so you can continue working with it.",
)}
</Text>
<Stack gap={4}>
<PasswordInput
label={t("encryptedPdfUnlock.password.label", "PDF password")}
placeholder={t(
"encryptedPdfUnlock.password.placeholder",
"Enter the PDF password",
)}
value={password}
onChange={(event) => onPasswordChange(event.currentTarget.value)}
onKeyDown={handleKeyDown}
disabled={isProcessing}
autoFocus
/>
{errorMessage ? (
<Text c="red" size="sm">
{errorMessage}
</Text>
) : null}
</Stack>
<Group justify="space-between">
<Button
variant="light"
color="var(--mantine-color-gray-8)"
onClick={onSkip}
disabled={isProcessing}
>
{t("encryptedPdfUnlock.skip", "Skip for now")}
</Button>
<Group gap="xs">
{remainingCount > 0 && (
<Button
variant="light"
onClick={onUnlockAll}
loading={isProcessing}
disabled={password.trim().length === 0}
>
{t("encryptedPdfUnlock.unlockAll", "Use for all ({{count}})", {
count: remainingCount + 1,
})}
</Button>
)}
<Button
onClick={onUnlock}
loading={isProcessing}
disabled={password.trim().length === 0}
>
{t("encryptedPdfUnlock.unlock", "Unlock & Continue")}
</Button>
</Group>
</Group>
</Stack>
</Modal>
);
};
export default EncryptedPdfUnlockModal;