mirror of
https://github.com/hanzo-apps/dataroom.git
synced 2026-10-30 14:47:36 +00:00
- Replace all Papermark branding with Hanzo Dataroom - Update metadata, titles, descriptions, OG tags - Update email templates footer and branding - Replace papermark.io/com URLs with dataroom.hanzo.ai - Update powered-by component - Update x-powered-by header - Update legal references to Hanzo AI, Inc. - Update social handles to @hanzoai - Update README, CLA, LICENSE, SECURITY docs
156 lines
4.4 KiB
TypeScript
156 lines
4.4 KiB
TypeScript
import { useCallback, useEffect, useState } from "react";
|
|
|
|
import { LinkPreset } from "@prisma/client";
|
|
import { motion } from "motion/react";
|
|
|
|
import { FADE_IN_ANIMATION_SETTINGS } from "@/lib/constants";
|
|
import { formatExpirationTime } from "@/lib/utils";
|
|
|
|
import { SmartDateTimePicker } from "@/components/ui/smart-date-time-picker";
|
|
|
|
import { DEFAULT_LINK_TYPE } from ".";
|
|
import LinkItem from "./link-item";
|
|
|
|
export default function ExpirationSection({
|
|
data,
|
|
setData,
|
|
presets,
|
|
}: {
|
|
data: DEFAULT_LINK_TYPE;
|
|
setData: React.Dispatch<React.SetStateAction<DEFAULT_LINK_TYPE>>;
|
|
presets: LinkPreset | null;
|
|
}) {
|
|
const { expiresAt } = data;
|
|
const [enabled, setEnabled] = useState<boolean>(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [customDate, setCustomDate] = useState<Date | null>(null);
|
|
|
|
useEffect(() => {
|
|
setEnabled(!!expiresAt);
|
|
setCustomDate(expiresAt);
|
|
}, [expiresAt]);
|
|
|
|
useEffect(() => {
|
|
if (presets?.expiresIn) {
|
|
setEnabled(true);
|
|
handlePresetChange(presets.expiresIn);
|
|
}
|
|
}, [presets]);
|
|
|
|
const handleEnableExpiration = () => {
|
|
if (enabled) {
|
|
// if expiration is currently set and we're toggling it off
|
|
setData({ ...data, expiresAt: null });
|
|
}
|
|
setEnabled(!enabled);
|
|
};
|
|
|
|
const handlePresetChange = (value: number) => {
|
|
setError(null);
|
|
|
|
const seconds = value;
|
|
if (!isNaN(seconds)) {
|
|
const newExpiresAt = new Date();
|
|
newExpiresAt.setSeconds(newExpiresAt.getSeconds() + seconds);
|
|
setData({ ...data, expiresAt: newExpiresAt });
|
|
setCustomDate(newExpiresAt);
|
|
}
|
|
};
|
|
|
|
const handleCustomDateChange = (date: Date | null) => {
|
|
if (!date) {
|
|
setError("Please select a valid date");
|
|
return;
|
|
}
|
|
|
|
const now = new Date();
|
|
if (date <= now) {
|
|
console.log("date <= now", now, date);
|
|
|
|
// Always add 1 day (86400000 milliseconds) to current time
|
|
const newDate = new Date(now.getTime() + 86400 * 1000);
|
|
|
|
setData({ ...data, expiresAt: newDate });
|
|
setCustomDate(newDate);
|
|
setError("Expiration time must be in the future. Set to tomorrow.");
|
|
return;
|
|
}
|
|
|
|
setData({ ...data, expiresAt: date });
|
|
setCustomDate(date);
|
|
setError(null);
|
|
};
|
|
|
|
const expirationTime = useCallback((date: Date | string) => {
|
|
const now = new Date();
|
|
const dateObj = typeof date === "string" ? new Date(date) : date;
|
|
const diffInSeconds = Math.floor(
|
|
(dateObj.getTime() - now.getTime()) / 1000,
|
|
);
|
|
return formatExpirationTime(diffInSeconds);
|
|
}, []);
|
|
|
|
const formatNaturalExpiration = useCallback((date: Date | string) => {
|
|
const now = new Date();
|
|
const dateObj = typeof date === "string" ? new Date(date) : date;
|
|
|
|
const formattedDate = dateObj.toLocaleDateString(undefined, {
|
|
weekday: "long",
|
|
month: "long",
|
|
day: "numeric",
|
|
});
|
|
|
|
const formattedTime = dateObj.toLocaleTimeString(undefined, {
|
|
hour: "numeric",
|
|
minute: "2-digit",
|
|
hour12: true,
|
|
});
|
|
|
|
if (dateObj.toDateString() === now.toDateString()) {
|
|
return `today at ${formattedTime}`;
|
|
}
|
|
|
|
const tomorrow = new Date(now);
|
|
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
if (dateObj.toDateString() === tomorrow.toDateString()) {
|
|
return `tomorrow at ${formattedTime}`;
|
|
}
|
|
|
|
return `on ${formattedDate} at ${formattedTime}`;
|
|
}, []);
|
|
|
|
return (
|
|
<div className="pb-5">
|
|
<LinkItem
|
|
title="Expiration Date"
|
|
enabled={enabled}
|
|
link="https://dataroom.hanzo.ai/help/article/expiration-date"
|
|
action={handleEnableExpiration}
|
|
tooltipContent="Set a date after which the link will no longer be accessible."
|
|
/>
|
|
|
|
{enabled && (
|
|
<motion.div className="mt-3 space-y-3" {...FADE_IN_ANIMATION_SETTINGS}>
|
|
<div className="flex flex-col space-y-2">
|
|
<SmartDateTimePicker
|
|
value={customDate}
|
|
onChange={handleCustomDateChange}
|
|
placeholder='e.g. "in 2 days", "next Friday at 3pm"'
|
|
/>
|
|
|
|
{expiresAt && (
|
|
<div className="text-xs text-muted-foreground">
|
|
<div>
|
|
Link will expire {formatNaturalExpiration(expiresAt)} (in{" "}
|
|
{expirationTime(expiresAt)})
|
|
</div>
|
|
</div>
|
|
)}
|
|
{error && <div className="text-xs text-red-500">{error}</div>}
|
|
</div>
|
|
</motion.div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|