Skip to content

Commit 77c154f

Browse files
committed
fix(ui): prevent sharing unsaved public links
Add an unsaved changes warning in the resume card share panel. Block copying or opening the public link if settings haven't been saved to the database to prevent users from accidentally sharing inactive links that result in a 404 error.
1 parent 2a49e4a commit 77c154f

1 file changed

Lines changed: 35 additions & 5 deletions

File tree

src/components/dashboard/resume-card.tsx

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ export function ResumeCard({ resume }: ResumeCardProps) {
164164
)}
165165

166166
{showSharePanel && !showDeleteConfirm ? (
167-
<div className="mt-4 border border-black p-3 space-y-3">
167+
<div className="mt-4 border border-black p-3 space-y-3 bg-gray-50">
168168
<span className="label-mono block">PUBLIC SHARE</span>
169169
<label className="flex items-center gap-2 text-xs font-bold uppercase tracking-wider">
170170
<input
@@ -213,7 +213,18 @@ export function ResumeCard({ resume }: ResumeCardProps) {
213213
onClick={(e) => e.currentTarget.select()}
214214
/>
215215
<button
216-
onClick={handleCopy}
216+
onClick={() => {
217+
const isDirty =
218+
isPublic !== resume.isPublic ||
219+
shareEmail !== (resume.data.personalInfo.shareEmail !== false) ||
220+
sharePhone !== (resume.data.personalInfo.sharePhone !== false) ||
221+
shareLocation !== (resume.data.personalInfo.shareLocation !== false);
222+
if (isDirty) {
223+
alert("Please save your share settings before copying the link!");
224+
return;
225+
}
226+
handleCopy();
227+
}}
217228
className="border border-black bg-black text-white px-4 py-2 text-xs font-bold uppercase tracking-wider hover:bg-white hover:text-black transition-colors duration-150 min-w-[80px]"
218229
>
219230
{isCopied ? "Copied" : "Copy"}
@@ -225,20 +236,39 @@ export function ResumeCard({ resume }: ResumeCardProps) {
225236
target="_blank"
226237
rel="noopener noreferrer"
227238
className="text-[10px] text-gray-500 hover:text-black hover:underline uppercase tracking-wider"
239+
onClick={(e) => {
240+
const isDirty =
241+
isPublic !== resume.isPublic ||
242+
shareEmail !== (resume.data.personalInfo.shareEmail !== false) ||
243+
sharePhone !== (resume.data.personalInfo.sharePhone !== false) ||
244+
shareLocation !== (resume.data.personalInfo.shareLocation !== false);
245+
if (isDirty) {
246+
e.preventDefault();
247+
alert("Please save your share settings first!");
248+
}
249+
}}
228250
>
229251
Open in new tab ↗
230252
</Link>
231253
</div>
232254
</div>
233255
) : null}
234256

235-
<div className="flex gap-2">
257+
<div className="flex flex-wrap items-center justify-between gap-2 pt-2 border-t border-gray-200">
258+
{(isPublic !== resume.isPublic ||
259+
shareEmail !== (resume.data.personalInfo.shareEmail !== false) ||
260+
sharePhone !== (resume.data.personalInfo.sharePhone !== false) ||
261+
shareLocation !== (resume.data.personalInfo.shareLocation !== false)) && (
262+
<span className="text-xs text-red-600 font-bold uppercase tracking-wider animate-pulse">
263+
⚠️ Unsaved Changes
264+
</span>
265+
)}
236266
<button
237267
onClick={handleSaveShare}
238268
disabled={isSavingShare}
239-
className="border border-black bg-black text-white px-3 py-1 text-xs font-bold uppercase tracking-wider hover:bg-white hover:text-black transition-colors duration-150 disabled:opacity-50"
269+
className="ml-auto border border-black bg-black text-white px-4 py-2 text-xs font-bold uppercase tracking-wider hover:bg-white hover:text-black transition-colors duration-150 disabled:opacity-50 inline-flex items-center gap-2"
240270
>
241-
{isSavingShare ? "Saving..." : "Save share settings"}
271+
{isSavingShare ? "Saving..." : "Save Settings"}
242272
</button>
243273
</div>
244274
</div>

0 commit comments

Comments
 (0)