Files
dataroom/components/links/link-sheet/expirationIn-section.tsx
zeekay 260fd6b8ce Rebrand from Papermark to Hanzo Dataroom
- 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
2026-03-01 19:02:19 -08:00

146 lines
3.7 KiB
TypeScript

import { useCallback, useEffect, useState } from "react";
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 ExpirationInSection({
data,
setData,
}: {
data: DEFAULT_LINK_TYPE & {
expiresIn?: number | null;
};
setData: React.Dispatch<
React.SetStateAction<
DEFAULT_LINK_TYPE & {
expiresIn?: number | null;
}
>
>;
}) {
const [enabled, setEnabled] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null);
const [customDate, setCustomDate] = useState<Date | null>(null);
const resetStates = useCallback(() => {
setError(null);
setCustomDate(null);
}, []);
// Initialize state based on existing expiresIn data
useEffect(() => {
if (!data.expiresIn) {
setEnabled(false);
resetStates();
return;
}
setEnabled(true);
if (data.expiresIn) {
const futureDate = new Date();
futureDate.setSeconds(futureDate.getSeconds() + data.expiresIn);
setCustomDate(futureDate);
}
}, [data.expiresIn]);
const handleEnableExpiration = useCallback(() => {
if (enabled) {
setData({
...data,
expiresIn: null,
});
resetStates();
} else {
// Enable with default 7 days expiration
setData({
...data,
expiresIn: 604800,
});
setError(null);
setCustomDate(null);
}
setEnabled(!enabled);
}, [enabled, data, resetStates]);
resetStates;
const handleCustomDateChange = useCallback(
(date: Date | null) => {
if (!date) {
return;
}
const now = new Date();
const diffMs = date.getTime() - now.getTime();
const diffSeconds = Math.ceil(diffMs / 1000);
if (diffSeconds <= 0) {
setError("Please enter a future duration");
return;
}
setData({
...data,
expiresIn: diffSeconds,
});
setCustomDate(date);
setError(null);
},
[data, setData],
);
// Custom formatter to show only the duration
const formatValue = useCallback((date: Date | null) => {
if (!date) return "";
const now = new Date();
const diffMs = date.getTime() - now.getTime();
const diffSeconds = Math.ceil(diffMs / 1000);
return "in " + formatExpirationTime(diffSeconds);
}, []);
return (
<div className="pb-5">
<LinkItem
title="Link Expires After"
enabled={enabled}
link="https://dataroom.hanzo.ai/help/article/expiration-date"
action={handleEnableExpiration}
tooltipContent="Set how long the link will remain active after creation."
/>
{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 hours" or "in 2 days"'
formatValue={formatValue}
showCalendarIcon={false}
/>
{data.expiresIn && (
<div className="text-xs text-muted-foreground">
<div>
Links will expire in {formatExpirationTime(data.expiresIn)}{" "}
after creation
</div>
</div>
)}
{error && <div className="text-xs text-red-500">{error}</div>}
</div>
</motion.div>
)}
</div>
);
}