fb11469a48
One-click job capture from any posting, reusing the existing jobimport/preview parser. - AddJobModal accepts initialUrl and auto-imports once on open - App reads a /?add=<encoded url> param, opens Add Job pre-filled, and strips the param from the address bar - QuickCaptureCard in Settings offers a draggable bookmarklet (href set via ref since React blocks javascript: URLs) plus copyable code - EN/NB translations; README feature note - 2 frontend tests; full suite green (22 suites / 50 tests) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
70 lines
2.5 KiB
TypeScript
70 lines
2.5 KiB
TypeScript
import React, { useEffect, useRef } from "react";
|
|
|
|
import { Box, Paper, TextField, Typography } from "@mui/material";
|
|
|
|
import { useI18n } from "../i18n/I18nProvider";
|
|
import { useToast } from "../toast";
|
|
|
|
/** The bookmarklet opens the app at /?add=<current page url>, which triggers quick-capture. */
|
|
function buildBookmarklet(origin: string): string {
|
|
// Kept as a single minified expression; opens a small popup so the user's tab is undisturbed.
|
|
return `javascript:void(window.open('${origin}/?add='+encodeURIComponent(location.href),'jobbjakt','width=520,height=720'))`;
|
|
}
|
|
|
|
export default function QuickCaptureCard() {
|
|
const { t } = useI18n();
|
|
const { toast } = useToast();
|
|
const linkRef = useRef<HTMLAnchorElement>(null);
|
|
const origin = typeof window !== "undefined" ? window.location.origin : "";
|
|
const bookmarklet = buildBookmarklet(origin);
|
|
|
|
// React refuses to render javascript: hrefs, so set it directly on the DOM node.
|
|
useEffect(() => {
|
|
if (linkRef.current) linkRef.current.setAttribute("href", bookmarklet);
|
|
}, [bookmarklet]);
|
|
|
|
return (
|
|
<Paper sx={{ p: 2 }}>
|
|
<Typography sx={{ fontWeight: 950, mb: 0.5 }}>{t("settingsQuickCaptureTitle")}</Typography>
|
|
<Typography variant="body2" sx={{ color: "text.secondary", mb: 1.5 }}>{t("settingsQuickCaptureSubtitle")}</Typography>
|
|
|
|
<Box sx={{ display: "flex", alignItems: "center", gap: 1.5, flexWrap: "wrap", mb: 1.5 }}>
|
|
<Box
|
|
component="a"
|
|
ref={linkRef}
|
|
onClick={(e: React.MouseEvent) => {
|
|
// Clicking (vs dragging) shouldn't navigate; the value is meant to be dragged to the bar.
|
|
e.preventDefault();
|
|
toast(t("settingsQuickCaptureDragHint"), "info");
|
|
}}
|
|
sx={{
|
|
display: "inline-block",
|
|
px: 2,
|
|
py: 1,
|
|
borderRadius: 2,
|
|
border: "1px solid",
|
|
borderColor: "primary.main",
|
|
color: "primary.main",
|
|
fontWeight: 800,
|
|
textDecoration: "none",
|
|
cursor: "grab",
|
|
userSelect: "none",
|
|
}}
|
|
>
|
|
{t("settingsQuickCaptureButton")}
|
|
</Box>
|
|
<Typography variant="body2" sx={{ color: "text.secondary" }}>{t("settingsQuickCaptureDragHint")}</Typography>
|
|
</Box>
|
|
|
|
<TextField
|
|
label={t("settingsQuickCaptureManual")}
|
|
value={bookmarklet}
|
|
fullWidth
|
|
size="small"
|
|
InputProps={{ readOnly: true }}
|
|
onFocus={(e) => e.target.select()}
|
|
/>
|
|
</Paper>
|
|
);
|
|
}
|