@rcnr/theme 2.0.4 → 2.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -41,4 +41,22 @@ interface RCNRMountainLogoProps {
41
41
  }
42
42
  declare function RCNRMountainLogo({ href, className, }: RCNRMountainLogoProps): react_jsx_runtime.JSX.Element;
43
43
 
44
- export { RCNRFooter, type RCNRFooterProps, RCNRHeader, type RCNRHeaderProps, RCNRMountainLogo, RCNRSubNav, type RCNRSubNavProps };
44
+ interface ReportIssueModalProps {
45
+ isOpen: boolean;
46
+ onClose: () => void;
47
+ toolName: string;
48
+ apiBaseUrl?: string;
49
+ userEmail?: string;
50
+ }
51
+ declare function ReportIssueModal({ isOpen, onClose, toolName, apiBaseUrl, userEmail, }: ReportIssueModalProps): react_jsx_runtime.JSX.Element | null;
52
+
53
+ interface RequestToolModalProps {
54
+ isOpen: boolean;
55
+ onClose: () => void;
56
+ toolName: string;
57
+ apiBaseUrl?: string;
58
+ userEmail?: string;
59
+ }
60
+ declare function RequestToolModal({ isOpen, onClose, toolName, apiBaseUrl, userEmail, }: RequestToolModalProps): react_jsx_runtime.JSX.Element | null;
61
+
62
+ export { RCNRFooter, type RCNRFooterProps, RCNRHeader, type RCNRHeaderProps, RCNRMountainLogo, RCNRSubNav, type RCNRSubNavProps, ReportIssueModal, RequestToolModal };
package/dist/index.d.ts CHANGED
@@ -41,4 +41,22 @@ interface RCNRMountainLogoProps {
41
41
  }
42
42
  declare function RCNRMountainLogo({ href, className, }: RCNRMountainLogoProps): react_jsx_runtime.JSX.Element;
43
43
 
44
- export { RCNRFooter, type RCNRFooterProps, RCNRHeader, type RCNRHeaderProps, RCNRMountainLogo, RCNRSubNav, type RCNRSubNavProps };
44
+ interface ReportIssueModalProps {
45
+ isOpen: boolean;
46
+ onClose: () => void;
47
+ toolName: string;
48
+ apiBaseUrl?: string;
49
+ userEmail?: string;
50
+ }
51
+ declare function ReportIssueModal({ isOpen, onClose, toolName, apiBaseUrl, userEmail, }: ReportIssueModalProps): react_jsx_runtime.JSX.Element | null;
52
+
53
+ interface RequestToolModalProps {
54
+ isOpen: boolean;
55
+ onClose: () => void;
56
+ toolName: string;
57
+ apiBaseUrl?: string;
58
+ userEmail?: string;
59
+ }
60
+ declare function RequestToolModal({ isOpen, onClose, toolName, apiBaseUrl, userEmail, }: RequestToolModalProps): react_jsx_runtime.JSX.Element | null;
61
+
62
+ export { RCNRFooter, type RCNRFooterProps, RCNRHeader, type RCNRHeaderProps, RCNRMountainLogo, RCNRSubNav, type RCNRSubNavProps, ReportIssueModal, RequestToolModal };
package/dist/index.js CHANGED
@@ -23,7 +23,9 @@ __export(index_exports, {
23
23
  RCNRFooter: () => RCNRFooter_default,
24
24
  RCNRHeader: () => RCNRHeader_default,
25
25
  RCNRMountainLogo: () => RCNRMountainLogo_default,
26
- RCNRSubNav: () => RCNRSubNav_default
26
+ RCNRSubNav: () => RCNRSubNav_default,
27
+ ReportIssueModal: () => ReportIssueModal,
28
+ RequestToolModal: () => RequestToolModal
27
29
  });
28
30
  module.exports = __toCommonJS(index_exports);
29
31
 
@@ -251,11 +253,253 @@ function RCNRFooter({
251
253
  ) });
252
254
  }
253
255
  var RCNRFooter_default = RCNRFooter;
256
+
257
+ // src/ReportIssueModal.tsx
258
+ var import_react = require("react");
259
+ var import_jsx_runtime5 = require("react/jsx-runtime");
260
+ function ReportIssueModal({
261
+ isOpen,
262
+ onClose,
263
+ toolName,
264
+ apiBaseUrl = "https://api.rcnr.net",
265
+ userEmail
266
+ }) {
267
+ const [description, setDescription] = (0, import_react.useState)("");
268
+ const [submitting, setSubmitting] = (0, import_react.useState)(false);
269
+ const [submitted, setSubmitted] = (0, import_react.useState)(false);
270
+ const [error, setError] = (0, import_react.useState)("");
271
+ const handleClose = (0, import_react.useCallback)(() => {
272
+ setDescription("");
273
+ setError("");
274
+ setSubmitted(false);
275
+ onClose();
276
+ }, [onClose]);
277
+ (0, import_react.useEffect)(() => {
278
+ if (!isOpen) return;
279
+ const onKey = (e) => {
280
+ if (e.key === "Escape") handleClose();
281
+ };
282
+ document.addEventListener("keydown", onKey);
283
+ return () => document.removeEventListener("keydown", onKey);
284
+ }, [isOpen, handleClose]);
285
+ if (!isOpen) return null;
286
+ const handleSubmit = async (e) => {
287
+ e.preventDefault();
288
+ if (!description.trim()) return;
289
+ setSubmitting(true);
290
+ setError("");
291
+ try {
292
+ const res = await fetch(`${apiBaseUrl}/api/feedback/report`, {
293
+ method: "POST",
294
+ headers: { "Content-Type": "application/json" },
295
+ body: JSON.stringify({ tool_name: toolName, description, user_email: userEmail })
296
+ });
297
+ if (res.ok) {
298
+ setSubmitted(true);
299
+ setTimeout(handleClose, 2e3);
300
+ } else {
301
+ setError("Something went wrong. Please try again.");
302
+ }
303
+ } catch {
304
+ setError("Could not send report. Check your connection.");
305
+ } finally {
306
+ setSubmitting(false);
307
+ }
308
+ };
309
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
310
+ "div",
311
+ {
312
+ className: "fixed inset-0 z-50 flex items-center justify-center p-4",
313
+ style: { background: "rgba(0,12,23,0.85)", backdropFilter: "blur(6px)" },
314
+ onClick: handleClose,
315
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
316
+ "div",
317
+ {
318
+ className: "relative glass-card rounded-2xl w-full max-w-md p-8",
319
+ style: { animation: "fadeIn 0.15s ease" },
320
+ onClick: (e) => e.stopPropagation(),
321
+ children: [
322
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
323
+ "button",
324
+ {
325
+ onClick: handleClose,
326
+ className: "absolute top-4 right-4 p-2 text-brand/50 hover:text-brand hover:bg-white/5 rounded-lg transition-colors",
327
+ "aria-label": "Close",
328
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M18 6L6 18M6 6l12 12" }) })
329
+ }
330
+ ),
331
+ submitted ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "text-center py-6", children: [
332
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w-12 h-12 rounded-full bg-emerald-500/15 flex items-center justify-center mx-auto mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", className: "text-emerald-400", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("polyline", { points: "20 6 9 17 4 12" }) }) }),
333
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-white font-semibold", children: "Report sent. We'll fix it fast." })
334
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
335
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { className: "text-xl font-bold text-white font-serif mb-1", children: "Report an Issue" }),
336
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-brand/50 text-sm mb-6", children: "Found a bug or something broken? Let us know." }),
337
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
338
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
339
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("label", { className: "block text-xs font-semibold text-brand/60 uppercase tracking-wider mb-2", children: "Tool" }),
340
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
341
+ "input",
342
+ {
343
+ type: "text",
344
+ value: toolName,
345
+ disabled: true,
346
+ className: "w-full px-4 py-2.5 rounded-xl bg-white/5 border border-brand/10 text-brand/40 text-sm"
347
+ }
348
+ )
349
+ ] }),
350
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
351
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("label", { className: "block text-xs font-semibold text-brand/60 uppercase tracking-wider mb-2", children: "What went wrong?" }),
352
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
353
+ "textarea",
354
+ {
355
+ value: description,
356
+ onChange: (e) => setDescription(e.target.value),
357
+ placeholder: "Describe the issue...",
358
+ rows: 4,
359
+ required: true,
360
+ className: "w-full px-4 py-3 rounded-xl bg-white/5 border border-brand/15 text-white placeholder-brand/30 text-sm resize-none focus:outline-none focus:border-brand/40 transition-colors"
361
+ }
362
+ )
363
+ ] }),
364
+ error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-red-400 text-sm", children: error }),
365
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
366
+ "button",
367
+ {
368
+ type: "submit",
369
+ disabled: submitting || !description.trim(),
370
+ className: "btn-ice w-full py-3 text-sm font-semibold rounded-xl disabled:opacity-40 disabled:cursor-not-allowed",
371
+ children: submitting ? "Sending..." : "Submit Report"
372
+ }
373
+ )
374
+ ] })
375
+ ] })
376
+ ]
377
+ }
378
+ )
379
+ }
380
+ );
381
+ }
382
+
383
+ // src/RequestToolModal.tsx
384
+ var import_react2 = require("react");
385
+ var import_jsx_runtime6 = require("react/jsx-runtime");
386
+ function RequestToolModal({
387
+ isOpen,
388
+ onClose,
389
+ toolName,
390
+ apiBaseUrl = "https://api.rcnr.net",
391
+ userEmail
392
+ }) {
393
+ const [description, setDescription] = (0, import_react2.useState)("");
394
+ const [submitting, setSubmitting] = (0, import_react2.useState)(false);
395
+ const [submitted, setSubmitted] = (0, import_react2.useState)(false);
396
+ const [error, setError] = (0, import_react2.useState)("");
397
+ const handleClose = (0, import_react2.useCallback)(() => {
398
+ setDescription("");
399
+ setError("");
400
+ setSubmitted(false);
401
+ onClose();
402
+ }, [onClose]);
403
+ (0, import_react2.useEffect)(() => {
404
+ if (!isOpen) return;
405
+ const onKey = (e) => {
406
+ if (e.key === "Escape") handleClose();
407
+ };
408
+ document.addEventListener("keydown", onKey);
409
+ return () => document.removeEventListener("keydown", onKey);
410
+ }, [isOpen, handleClose]);
411
+ if (!isOpen) return null;
412
+ const handleSubmit = async (e) => {
413
+ e.preventDefault();
414
+ if (!description.trim()) return;
415
+ setSubmitting(true);
416
+ setError("");
417
+ try {
418
+ const res = await fetch(`${apiBaseUrl}/api/feedback/request`, {
419
+ method: "POST",
420
+ headers: { "Content-Type": "application/json" },
421
+ body: JSON.stringify({ tool_name: toolName, description, user_email: userEmail })
422
+ });
423
+ if (res.ok) {
424
+ setSubmitted(true);
425
+ setTimeout(handleClose, 2e3);
426
+ } else {
427
+ setError("Something went wrong. Please try again.");
428
+ }
429
+ } catch {
430
+ setError("Could not send request. Check your connection.");
431
+ } finally {
432
+ setSubmitting(false);
433
+ }
434
+ };
435
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
436
+ "div",
437
+ {
438
+ className: "fixed inset-0 z-50 flex items-center justify-center p-4",
439
+ style: { background: "rgba(0,12,23,0.85)", backdropFilter: "blur(6px)" },
440
+ onClick: handleClose,
441
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
442
+ "div",
443
+ {
444
+ className: "relative glass-card rounded-2xl w-full max-w-md p-8",
445
+ style: { animation: "fadeIn 0.15s ease" },
446
+ onClick: (e) => e.stopPropagation(),
447
+ children: [
448
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
449
+ "button",
450
+ {
451
+ onClick: handleClose,
452
+ className: "absolute top-4 right-4 p-2 text-brand/50 hover:text-brand hover:bg-white/5 rounded-lg transition-colors",
453
+ "aria-label": "Close",
454
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M18 6L6 18M6 6l12 12" }) })
455
+ }
456
+ ),
457
+ submitted ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "text-center py-6", children: [
458
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w-12 h-12 rounded-full bg-brand/10 flex items-center justify-center mx-auto mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", className: "text-brand", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("polyline", { points: "20 6 9 17 4 12" }) }) }),
459
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-white font-semibold", children: "Request received. Thanks!" })
460
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
461
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h2", { className: "text-xl font-bold text-white font-serif mb-1", children: "Request a Tool" }),
462
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-brand/50 text-sm mb-6", children: "Have an idea for something we should build?" }),
463
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
464
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
465
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("label", { className: "block text-xs font-semibold text-brand/60 uppercase tracking-wider mb-2", children: "Describe what you need" }),
466
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
467
+ "textarea",
468
+ {
469
+ value: description,
470
+ onChange: (e) => setDescription(e.target.value),
471
+ placeholder: "What problem would this tool solve? What would it do?",
472
+ rows: 5,
473
+ required: true,
474
+ className: "w-full px-4 py-3 rounded-xl bg-white/5 border border-brand/15 text-white placeholder-brand/30 text-sm resize-none focus:outline-none focus:border-brand/40 transition-colors"
475
+ }
476
+ )
477
+ ] }),
478
+ error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-red-400 text-sm", children: error }),
479
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
480
+ "button",
481
+ {
482
+ type: "submit",
483
+ disabled: submitting || !description.trim(),
484
+ className: "btn-ice w-full py-3 text-sm font-semibold rounded-xl disabled:opacity-40 disabled:cursor-not-allowed",
485
+ children: submitting ? "Sending..." : "Submit Request"
486
+ }
487
+ )
488
+ ] })
489
+ ] })
490
+ ]
491
+ }
492
+ )
493
+ }
494
+ );
495
+ }
254
496
  // Annotate the CommonJS export names for ESM import in node:
255
497
  0 && (module.exports = {
256
498
  RCNRFooter,
257
499
  RCNRHeader,
258
500
  RCNRMountainLogo,
259
- RCNRSubNav
501
+ RCNRSubNav,
502
+ ReportIssueModal,
503
+ RequestToolModal
260
504
  });
261
505
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/RCNRMountainLogo.tsx","../src/RCNRHeader.tsx","../src/RCNRSubNav.tsx","../src/RCNRFooter.tsx"],"sourcesContent":["export { default as RCNRHeader } from './RCNRHeader'\r\nexport { default as RCNRSubNav } from './RCNRSubNav'\r\nexport { default as RCNRFooter } from './RCNRFooter'\r\nexport { default as RCNRMountainLogo } from './RCNRMountainLogo'\r\n\r\nexport type {\r\n RCNRHeaderProps,\r\n RCNRSubNavProps,\r\n RCNRFooterProps,\r\n} from './types'\r\n","interface RCNRMountainLogoProps {\r\n href?: string\r\n className?: string\r\n}\r\n\r\nfunction RCNRMountainLogo({\r\n href = 'https://teacher.rcnr.net',\r\n className = '',\r\n}: RCNRMountainLogoProps) {\r\n return (\r\n <a\r\n href={href}\r\n className={`flex items-center justify-center w-10 h-10 rounded-lg bg-brand/10 hover:bg-brand/20 transition-colors ${className}`}\r\n title=\"Back to Dashboard\"\r\n >\r\n <svg\r\n width=\"28\"\r\n height=\"24\"\r\n viewBox=\"0 0 120 100\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <path\r\n d=\"M10,90l26.48-39.76h.31s4.54,5.02,4.54,5.02l.32-.16,23.06-37.14,17.34,28.63,3.65-4.61,30.22,48.03h-8.43c-7.17-12.26-15.51-24.35-23.06-36.26-1.43.52-2.03,3.6-3.49,3.97l-16.31-25.93-21.87,34.36-5.09-5.01-19.48,28.87h-8.19Z\"\r\n fill=\"#99D9D9\"\r\n />\r\n <path\r\n d=\"M89.84,90h-5.73c-6.34-8.18-12.93-16.89-19.64-24.65-6.66,8.19-13.04,16.6-19.89,24.65h-5.81l25.69-39.76,25.37,39.76Z\"\r\n fill=\"#99D9D9\"\r\n />\r\n </svg>\r\n </a>\r\n )\r\n}\r\n\r\nexport default RCNRMountainLogo\r\n","import type { ReactNode } from 'react'\r\nimport type { RCNRHeaderProps } from './types'\r\nimport RCNRMountainLogo from './RCNRMountainLogo'\r\n\r\nfunction NavButton({\r\n onClick,\r\n icon,\r\n label,\r\n title,\r\n}: {\r\n onClick: () => void\r\n icon: ReactNode\r\n label: string\r\n title?: string\r\n}) {\r\n return (\r\n <button\r\n onClick={onClick}\r\n className=\"flex items-center gap-2 px-3 py-2 text-brand/70 hover:text-brand hover:bg-brand/5 rounded-lg transition-colors\"\r\n title={title ?? label}\r\n >\r\n {icon}\r\n <span className=\"hidden md:inline text-sm\">{label}</span>\r\n </button>\r\n )\r\n}\r\n\r\nconst defaultReportIssue = () =>\r\n window.open('mailto:support@rcnr.net?subject=Bug%20Report', '_blank')\r\n\r\nconst defaultRequestTool = () =>\r\n window.open('mailto:support@rcnr.net?subject=Feature%20Request', '_blank')\r\n\r\nfunction RCNRHeader({\r\n toolName,\r\n dashboardUrl = 'https://teacher.rcnr.net',\r\n extraNavItems,\r\n userAvatar,\r\n onHowItWorks,\r\n onReportIssue = defaultReportIssue,\r\n onRequestTool = defaultRequestTool,\r\n}: RCNRHeaderProps) {\r\n return (\r\n <header className=\"glass-card border-b border-brand/15 px-6 py-4\">\r\n <div className=\"flex items-center justify-between\">\r\n {/* Left: Logo + Tool Name */}\r\n <div className=\"flex items-center gap-4\">\r\n <RCNRMountainLogo href={dashboardUrl} />\r\n <span className=\"text-xl font-serif text-brand\">{toolName}</span>\r\n </div>\r\n\r\n {/* Right: Nav Actions */}\r\n <div className=\"flex items-center gap-2\">\r\n {/* Tool-specific nav items first */}\r\n {extraNavItems?.map((item) => (\r\n <NavButton\r\n key={item.label}\r\n onClick={item.onClick}\r\n icon={item.icon}\r\n label={item.label}\r\n />\r\n ))}\r\n\r\n {/* Standard nav items in fixed order */}\r\n {onHowItWorks && (\r\n <NavButton\r\n onClick={onHowItWorks}\r\n label=\"How It Works\"\r\n icon={\r\n <svg\r\n className=\"w-[18px] h-[18px]\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3\"\r\n />\r\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\r\n </svg>\r\n }\r\n />\r\n )}\r\n\r\n <NavButton\r\n onClick={onReportIssue}\r\n label=\"Report Issue\"\r\n icon={\r\n <svg\r\n className=\"w-[18px] h-[18px]\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\r\n />\r\n </svg>\r\n }\r\n />\r\n\r\n <NavButton\r\n onClick={onRequestTool}\r\n label=\"Request Tool\"\r\n icon={\r\n <svg\r\n className=\"w-[18px] h-[18px]\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z\"\r\n />\r\n </svg>\r\n }\r\n />\r\n\r\n {userAvatar}\r\n </div>\r\n </div>\r\n </header>\r\n )\r\n}\r\n\r\nexport default RCNRHeader\r\n","import type { RCNRSubNavProps } from './types'\r\n\r\nfunction RCNRSubNav({ tabs }: RCNRSubNavProps) {\r\n return (\r\n <nav className=\"flex items-center gap-1 px-6 py-2 border-b border-brand/10 bg-surface/50\">\r\n {tabs.map((tab) => {\r\n const isWarning = tab.variant === 'warning'\r\n const activeClass = isWarning\r\n ? 'bg-warning/10 text-warning border border-warning/20'\r\n : 'bg-brand/15 text-brand'\r\n const inactiveClass = isWarning\r\n ? 'text-warning/70 hover:text-warning hover:bg-warning/5 border border-warning/10'\r\n : 'text-brand/50 hover:text-brand hover:bg-brand/5'\r\n\r\n const className = `flex items-center gap-2 px-4 py-2 rounded-lg text-sm transition-colors ${\r\n tab.active ? activeClass : inactiveClass\r\n }`\r\n\r\n if (tab.href) {\r\n return (\r\n <a key={tab.label} href={tab.href} className={className}>\r\n {tab.icon}\r\n <span>{tab.label}</span>\r\n </a>\r\n )\r\n }\r\n\r\n return (\r\n <button\r\n key={tab.label}\r\n onClick={tab.onClick}\r\n className={className}\r\n >\r\n {tab.icon}\r\n <span>{tab.label}</span>\r\n </button>\r\n )\r\n })}\r\n </nav>\r\n )\r\n}\r\n\r\nexport default RCNRSubNav\r\n","import type { RCNRFooterProps } from './types'\r\n\r\nfunction RCNRFooter({\r\n toolName,\r\n linkUrl = 'https://rcnr.net',\r\n}: RCNRFooterProps) {\r\n return (\r\n <footer className=\"mt-auto py-4 text-center text-sm text-brand-dark/50\">\r\n <a\r\n href={linkUrl}\r\n className=\"hover:text-brand transition-colors\"\r\n >\r\n {toolName} — Part of the RCNR Teacher Toolbox\r\n </a>\r\n </footer>\r\n )\r\n}\r\n\r\nexport default RCNRFooter\r\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/RCNRMountainLogo.tsx","../src/RCNRHeader.tsx","../src/RCNRSubNav.tsx","../src/RCNRFooter.tsx","../src/ReportIssueModal.tsx","../src/RequestToolModal.tsx"],"sourcesContent":["export { default as RCNRHeader } from './RCNRHeader'\r\nexport { default as RCNRSubNav } from './RCNRSubNav'\r\nexport { default as RCNRFooter } from './RCNRFooter'\r\nexport { default as RCNRMountainLogo } from './RCNRMountainLogo'\r\nexport { ReportIssueModal } from './ReportIssueModal'\r\nexport { RequestToolModal } from './RequestToolModal'\r\n\r\nexport type {\r\n RCNRHeaderProps,\r\n RCNRSubNavProps,\r\n RCNRFooterProps,\r\n} from './types'\r\n","interface RCNRMountainLogoProps {\r\n href?: string\r\n className?: string\r\n}\r\n\r\nfunction RCNRMountainLogo({\r\n href = 'https://teacher.rcnr.net',\r\n className = '',\r\n}: RCNRMountainLogoProps) {\r\n return (\r\n <a\r\n href={href}\r\n className={`flex items-center justify-center w-10 h-10 rounded-lg bg-brand/10 hover:bg-brand/20 transition-colors ${className}`}\r\n title=\"Back to Dashboard\"\r\n >\r\n <svg\r\n width=\"28\"\r\n height=\"24\"\r\n viewBox=\"0 0 120 100\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <path\r\n d=\"M10,90l26.48-39.76h.31s4.54,5.02,4.54,5.02l.32-.16,23.06-37.14,17.34,28.63,3.65-4.61,30.22,48.03h-8.43c-7.17-12.26-15.51-24.35-23.06-36.26-1.43.52-2.03,3.6-3.49,3.97l-16.31-25.93-21.87,34.36-5.09-5.01-19.48,28.87h-8.19Z\"\r\n fill=\"#99D9D9\"\r\n />\r\n <path\r\n d=\"M89.84,90h-5.73c-6.34-8.18-12.93-16.89-19.64-24.65-6.66,8.19-13.04,16.6-19.89,24.65h-5.81l25.69-39.76,25.37,39.76Z\"\r\n fill=\"#99D9D9\"\r\n />\r\n </svg>\r\n </a>\r\n )\r\n}\r\n\r\nexport default RCNRMountainLogo\r\n","import type { ReactNode } from 'react'\r\nimport type { RCNRHeaderProps } from './types'\r\nimport RCNRMountainLogo from './RCNRMountainLogo'\r\n\r\nfunction NavButton({\r\n onClick,\r\n icon,\r\n label,\r\n title,\r\n}: {\r\n onClick: () => void\r\n icon: ReactNode\r\n label: string\r\n title?: string\r\n}) {\r\n return (\r\n <button\r\n onClick={onClick}\r\n className=\"flex items-center gap-2 px-3 py-2 text-brand/70 hover:text-brand hover:bg-brand/5 rounded-lg transition-colors\"\r\n title={title ?? label}\r\n >\r\n {icon}\r\n <span className=\"hidden md:inline text-sm\">{label}</span>\r\n </button>\r\n )\r\n}\r\n\r\nconst defaultReportIssue = () =>\r\n window.open('mailto:support@rcnr.net?subject=Bug%20Report', '_blank')\r\n\r\nconst defaultRequestTool = () =>\r\n window.open('mailto:support@rcnr.net?subject=Feature%20Request', '_blank')\r\n\r\nfunction RCNRHeader({\r\n toolName,\r\n dashboardUrl = 'https://teacher.rcnr.net',\r\n extraNavItems,\r\n userAvatar,\r\n onHowItWorks,\r\n onReportIssue = defaultReportIssue,\r\n onRequestTool = defaultRequestTool,\r\n}: RCNRHeaderProps) {\r\n return (\r\n <header className=\"glass-card border-b border-brand/15 px-6 py-4\">\r\n <div className=\"flex items-center justify-between\">\r\n {/* Left: Logo + Tool Name */}\r\n <div className=\"flex items-center gap-4\">\r\n <RCNRMountainLogo href={dashboardUrl} />\r\n <span className=\"text-xl font-serif text-brand\">{toolName}</span>\r\n </div>\r\n\r\n {/* Right: Nav Actions */}\r\n <div className=\"flex items-center gap-2\">\r\n {/* Tool-specific nav items first */}\r\n {extraNavItems?.map((item) => (\r\n <NavButton\r\n key={item.label}\r\n onClick={item.onClick}\r\n icon={item.icon}\r\n label={item.label}\r\n />\r\n ))}\r\n\r\n {/* Standard nav items in fixed order */}\r\n {onHowItWorks && (\r\n <NavButton\r\n onClick={onHowItWorks}\r\n label=\"How It Works\"\r\n icon={\r\n <svg\r\n className=\"w-[18px] h-[18px]\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3\"\r\n />\r\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\r\n </svg>\r\n }\r\n />\r\n )}\r\n\r\n <NavButton\r\n onClick={onReportIssue}\r\n label=\"Report Issue\"\r\n icon={\r\n <svg\r\n className=\"w-[18px] h-[18px]\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\r\n />\r\n </svg>\r\n }\r\n />\r\n\r\n <NavButton\r\n onClick={onRequestTool}\r\n label=\"Request Tool\"\r\n icon={\r\n <svg\r\n className=\"w-[18px] h-[18px]\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z\"\r\n />\r\n </svg>\r\n }\r\n />\r\n\r\n {userAvatar}\r\n </div>\r\n </div>\r\n </header>\r\n )\r\n}\r\n\r\nexport default RCNRHeader\r\n","import type { RCNRSubNavProps } from './types'\r\n\r\nfunction RCNRSubNav({ tabs }: RCNRSubNavProps) {\r\n return (\r\n <nav className=\"flex items-center gap-1 px-6 py-2 border-b border-brand/10 bg-surface/50\">\r\n {tabs.map((tab) => {\r\n const isWarning = tab.variant === 'warning'\r\n const activeClass = isWarning\r\n ? 'bg-warning/10 text-warning border border-warning/20'\r\n : 'bg-brand/15 text-brand'\r\n const inactiveClass = isWarning\r\n ? 'text-warning/70 hover:text-warning hover:bg-warning/5 border border-warning/10'\r\n : 'text-brand/50 hover:text-brand hover:bg-brand/5'\r\n\r\n const className = `flex items-center gap-2 px-4 py-2 rounded-lg text-sm transition-colors ${\r\n tab.active ? activeClass : inactiveClass\r\n }`\r\n\r\n if (tab.href) {\r\n return (\r\n <a key={tab.label} href={tab.href} className={className}>\r\n {tab.icon}\r\n <span>{tab.label}</span>\r\n </a>\r\n )\r\n }\r\n\r\n return (\r\n <button\r\n key={tab.label}\r\n onClick={tab.onClick}\r\n className={className}\r\n >\r\n {tab.icon}\r\n <span>{tab.label}</span>\r\n </button>\r\n )\r\n })}\r\n </nav>\r\n )\r\n}\r\n\r\nexport default RCNRSubNav\r\n","import type { RCNRFooterProps } from './types'\r\n\r\nfunction RCNRFooter({\r\n toolName,\r\n linkUrl = 'https://rcnr.net',\r\n}: RCNRFooterProps) {\r\n return (\r\n <footer className=\"mt-auto py-4 text-center text-sm text-brand-dark/50\">\r\n <a\r\n href={linkUrl}\r\n className=\"hover:text-brand transition-colors\"\r\n >\r\n {toolName} — Part of the RCNR Teacher Toolbox\r\n </a>\r\n </footer>\r\n )\r\n}\r\n\r\nexport default RCNRFooter\r\n","import { useState, useEffect, useCallback } from 'react'\n\ninterface ReportIssueModalProps {\n isOpen: boolean\n onClose: () => void\n toolName: string\n apiBaseUrl?: string\n userEmail?: string\n}\n\nexport function ReportIssueModal({\n isOpen,\n onClose,\n toolName,\n apiBaseUrl = 'https://api.rcnr.net',\n userEmail,\n}: ReportIssueModalProps) {\n const [description, setDescription] = useState('')\n const [submitting, setSubmitting] = useState(false)\n const [submitted, setSubmitted] = useState(false)\n const [error, setError] = useState('')\n\n const handleClose = useCallback(() => {\n setDescription('')\n setError('')\n setSubmitted(false)\n onClose()\n }, [onClose])\n\n useEffect(() => {\n if (!isOpen) return\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') handleClose() }\n document.addEventListener('keydown', onKey)\n return () => document.removeEventListener('keydown', onKey)\n }, [isOpen, handleClose])\n\n if (!isOpen) return null\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n if (!description.trim()) return\n setSubmitting(true)\n setError('')\n try {\n const res = await fetch(`${apiBaseUrl}/api/feedback/report`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ tool_name: toolName, description, user_email: userEmail }),\n })\n if (res.ok) {\n setSubmitted(true)\n setTimeout(handleClose, 2000)\n } else {\n setError('Something went wrong. Please try again.')\n }\n } catch {\n setError('Could not send report. Check your connection.')\n } finally {\n setSubmitting(false)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center p-4\"\n style={{ background: 'rgba(0,12,23,0.85)', backdropFilter: 'blur(6px)' }}\n onClick={handleClose}\n >\n <div\n className=\"relative glass-card rounded-2xl w-full max-w-md p-8\"\n style={{ animation: 'fadeIn 0.15s ease' }}\n onClick={(e) => e.stopPropagation()}\n >\n <button\n onClick={handleClose}\n className=\"absolute top-4 right-4 p-2 text-brand/50 hover:text-brand hover:bg-white/5 rounded-lg transition-colors\"\n aria-label=\"Close\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n </button>\n\n {submitted ? (\n <div className=\"text-center py-6\">\n <div className=\"w-12 h-12 rounded-full bg-emerald-500/15 flex items-center justify-center mx-auto mb-4\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" className=\"text-emerald-400\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </div>\n <p className=\"text-white font-semibold\">Report sent. We'll fix it fast.</p>\n </div>\n ) : (\n <>\n <h2 className=\"text-xl font-bold text-white font-serif mb-1\">Report an Issue</h2>\n <p className=\"text-brand/50 text-sm mb-6\">Found a bug or something broken? Let us know.</p>\n\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <div>\n <label className=\"block text-xs font-semibold text-brand/60 uppercase tracking-wider mb-2\">Tool</label>\n <input\n type=\"text\"\n value={toolName}\n disabled\n className=\"w-full px-4 py-2.5 rounded-xl bg-white/5 border border-brand/10 text-brand/40 text-sm\"\n />\n </div>\n\n <div>\n <label className=\"block text-xs font-semibold text-brand/60 uppercase tracking-wider mb-2\">\n What went wrong?\n </label>\n <textarea\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Describe the issue...\"\n rows={4}\n required\n className=\"w-full px-4 py-3 rounded-xl bg-white/5 border border-brand/15 text-white placeholder-brand/30 text-sm resize-none focus:outline-none focus:border-brand/40 transition-colors\"\n />\n </div>\n\n {error && <p className=\"text-red-400 text-sm\">{error}</p>}\n\n <button\n type=\"submit\"\n disabled={submitting || !description.trim()}\n className=\"btn-ice w-full py-3 text-sm font-semibold rounded-xl disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n {submitting ? 'Sending...' : 'Submit Report'}\n </button>\n </form>\n </>\n )}\n </div>\n </div>\n )\n}\n","import { useState, useEffect, useCallback } from 'react'\n\ninterface RequestToolModalProps {\n isOpen: boolean\n onClose: () => void\n toolName: string\n apiBaseUrl?: string\n userEmail?: string\n}\n\nexport function RequestToolModal({\n isOpen,\n onClose,\n toolName,\n apiBaseUrl = 'https://api.rcnr.net',\n userEmail,\n}: RequestToolModalProps) {\n const [description, setDescription] = useState('')\n const [submitting, setSubmitting] = useState(false)\n const [submitted, setSubmitted] = useState(false)\n const [error, setError] = useState('')\n\n const handleClose = useCallback(() => {\n setDescription('')\n setError('')\n setSubmitted(false)\n onClose()\n }, [onClose])\n\n useEffect(() => {\n if (!isOpen) return\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') handleClose() }\n document.addEventListener('keydown', onKey)\n return () => document.removeEventListener('keydown', onKey)\n }, [isOpen, handleClose])\n\n if (!isOpen) return null\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n if (!description.trim()) return\n setSubmitting(true)\n setError('')\n try {\n const res = await fetch(`${apiBaseUrl}/api/feedback/request`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ tool_name: toolName, description, user_email: userEmail }),\n })\n if (res.ok) {\n setSubmitted(true)\n setTimeout(handleClose, 2000)\n } else {\n setError('Something went wrong. Please try again.')\n }\n } catch {\n setError('Could not send request. Check your connection.')\n } finally {\n setSubmitting(false)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center p-4\"\n style={{ background: 'rgba(0,12,23,0.85)', backdropFilter: 'blur(6px)' }}\n onClick={handleClose}\n >\n <div\n className=\"relative glass-card rounded-2xl w-full max-w-md p-8\"\n style={{ animation: 'fadeIn 0.15s ease' }}\n onClick={(e) => e.stopPropagation()}\n >\n <button\n onClick={handleClose}\n className=\"absolute top-4 right-4 p-2 text-brand/50 hover:text-brand hover:bg-white/5 rounded-lg transition-colors\"\n aria-label=\"Close\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n </button>\n\n {submitted ? (\n <div className=\"text-center py-6\">\n <div className=\"w-12 h-12 rounded-full bg-brand/10 flex items-center justify-center mx-auto mb-4\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" className=\"text-brand\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </div>\n <p className=\"text-white font-semibold\">Request received. Thanks!</p>\n </div>\n ) : (\n <>\n <h2 className=\"text-xl font-bold text-white font-serif mb-1\">Request a Tool</h2>\n <p className=\"text-brand/50 text-sm mb-6\">Have an idea for something we should build?</p>\n\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <div>\n <label className=\"block text-xs font-semibold text-brand/60 uppercase tracking-wider mb-2\">\n Describe what you need\n </label>\n <textarea\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"What problem would this tool solve? What would it do?\"\n rows={5}\n required\n className=\"w-full px-4 py-3 rounded-xl bg-white/5 border border-brand/15 text-white placeholder-brand/30 text-sm resize-none focus:outline-none focus:border-brand/40 transition-colors\"\n />\n </div>\n\n {error && <p className=\"text-red-400 text-sm\">{error}</p>}\n\n <button\n type=\"submit\"\n disabled={submitting || !description.trim()}\n className=\"btn-ice w-full py-3 text-sm font-semibold rounded-xl disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n {submitting ? 'Sending...' : 'Submit Request'}\n </button>\n </form>\n </>\n )}\n </div>\n </div>\n )\n}\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime"]}
package/dist/index.mjs CHANGED
@@ -222,10 +222,252 @@ function RCNRFooter({
222
222
  ) });
223
223
  }
224
224
  var RCNRFooter_default = RCNRFooter;
225
+
226
+ // src/ReportIssueModal.tsx
227
+ import { useState, useEffect, useCallback } from "react";
228
+ import { Fragment, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
229
+ function ReportIssueModal({
230
+ isOpen,
231
+ onClose,
232
+ toolName,
233
+ apiBaseUrl = "https://api.rcnr.net",
234
+ userEmail
235
+ }) {
236
+ const [description, setDescription] = useState("");
237
+ const [submitting, setSubmitting] = useState(false);
238
+ const [submitted, setSubmitted] = useState(false);
239
+ const [error, setError] = useState("");
240
+ const handleClose = useCallback(() => {
241
+ setDescription("");
242
+ setError("");
243
+ setSubmitted(false);
244
+ onClose();
245
+ }, [onClose]);
246
+ useEffect(() => {
247
+ if (!isOpen) return;
248
+ const onKey = (e) => {
249
+ if (e.key === "Escape") handleClose();
250
+ };
251
+ document.addEventListener("keydown", onKey);
252
+ return () => document.removeEventListener("keydown", onKey);
253
+ }, [isOpen, handleClose]);
254
+ if (!isOpen) return null;
255
+ const handleSubmit = async (e) => {
256
+ e.preventDefault();
257
+ if (!description.trim()) return;
258
+ setSubmitting(true);
259
+ setError("");
260
+ try {
261
+ const res = await fetch(`${apiBaseUrl}/api/feedback/report`, {
262
+ method: "POST",
263
+ headers: { "Content-Type": "application/json" },
264
+ body: JSON.stringify({ tool_name: toolName, description, user_email: userEmail })
265
+ });
266
+ if (res.ok) {
267
+ setSubmitted(true);
268
+ setTimeout(handleClose, 2e3);
269
+ } else {
270
+ setError("Something went wrong. Please try again.");
271
+ }
272
+ } catch {
273
+ setError("Could not send report. Check your connection.");
274
+ } finally {
275
+ setSubmitting(false);
276
+ }
277
+ };
278
+ return /* @__PURE__ */ jsx5(
279
+ "div",
280
+ {
281
+ className: "fixed inset-0 z-50 flex items-center justify-center p-4",
282
+ style: { background: "rgba(0,12,23,0.85)", backdropFilter: "blur(6px)" },
283
+ onClick: handleClose,
284
+ children: /* @__PURE__ */ jsxs5(
285
+ "div",
286
+ {
287
+ className: "relative glass-card rounded-2xl w-full max-w-md p-8",
288
+ style: { animation: "fadeIn 0.15s ease" },
289
+ onClick: (e) => e.stopPropagation(),
290
+ children: [
291
+ /* @__PURE__ */ jsx5(
292
+ "button",
293
+ {
294
+ onClick: handleClose,
295
+ className: "absolute top-4 right-4 p-2 text-brand/50 hover:text-brand hover:bg-white/5 rounded-lg transition-colors",
296
+ "aria-label": "Close",
297
+ children: /* @__PURE__ */ jsx5("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx5("path", { d: "M18 6L6 18M6 6l12 12" }) })
298
+ }
299
+ ),
300
+ submitted ? /* @__PURE__ */ jsxs5("div", { className: "text-center py-6", children: [
301
+ /* @__PURE__ */ jsx5("div", { className: "w-12 h-12 rounded-full bg-emerald-500/15 flex items-center justify-center mx-auto mb-4", children: /* @__PURE__ */ jsx5("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", className: "text-emerald-400", children: /* @__PURE__ */ jsx5("polyline", { points: "20 6 9 17 4 12" }) }) }),
302
+ /* @__PURE__ */ jsx5("p", { className: "text-white font-semibold", children: "Report sent. We'll fix it fast." })
303
+ ] }) : /* @__PURE__ */ jsxs5(Fragment, { children: [
304
+ /* @__PURE__ */ jsx5("h2", { className: "text-xl font-bold text-white font-serif mb-1", children: "Report an Issue" }),
305
+ /* @__PURE__ */ jsx5("p", { className: "text-brand/50 text-sm mb-6", children: "Found a bug or something broken? Let us know." }),
306
+ /* @__PURE__ */ jsxs5("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
307
+ /* @__PURE__ */ jsxs5("div", { children: [
308
+ /* @__PURE__ */ jsx5("label", { className: "block text-xs font-semibold text-brand/60 uppercase tracking-wider mb-2", children: "Tool" }),
309
+ /* @__PURE__ */ jsx5(
310
+ "input",
311
+ {
312
+ type: "text",
313
+ value: toolName,
314
+ disabled: true,
315
+ className: "w-full px-4 py-2.5 rounded-xl bg-white/5 border border-brand/10 text-brand/40 text-sm"
316
+ }
317
+ )
318
+ ] }),
319
+ /* @__PURE__ */ jsxs5("div", { children: [
320
+ /* @__PURE__ */ jsx5("label", { className: "block text-xs font-semibold text-brand/60 uppercase tracking-wider mb-2", children: "What went wrong?" }),
321
+ /* @__PURE__ */ jsx5(
322
+ "textarea",
323
+ {
324
+ value: description,
325
+ onChange: (e) => setDescription(e.target.value),
326
+ placeholder: "Describe the issue...",
327
+ rows: 4,
328
+ required: true,
329
+ className: "w-full px-4 py-3 rounded-xl bg-white/5 border border-brand/15 text-white placeholder-brand/30 text-sm resize-none focus:outline-none focus:border-brand/40 transition-colors"
330
+ }
331
+ )
332
+ ] }),
333
+ error && /* @__PURE__ */ jsx5("p", { className: "text-red-400 text-sm", children: error }),
334
+ /* @__PURE__ */ jsx5(
335
+ "button",
336
+ {
337
+ type: "submit",
338
+ disabled: submitting || !description.trim(),
339
+ className: "btn-ice w-full py-3 text-sm font-semibold rounded-xl disabled:opacity-40 disabled:cursor-not-allowed",
340
+ children: submitting ? "Sending..." : "Submit Report"
341
+ }
342
+ )
343
+ ] })
344
+ ] })
345
+ ]
346
+ }
347
+ )
348
+ }
349
+ );
350
+ }
351
+
352
+ // src/RequestToolModal.tsx
353
+ import { useState as useState2, useEffect as useEffect2, useCallback as useCallback2 } from "react";
354
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
355
+ function RequestToolModal({
356
+ isOpen,
357
+ onClose,
358
+ toolName,
359
+ apiBaseUrl = "https://api.rcnr.net",
360
+ userEmail
361
+ }) {
362
+ const [description, setDescription] = useState2("");
363
+ const [submitting, setSubmitting] = useState2(false);
364
+ const [submitted, setSubmitted] = useState2(false);
365
+ const [error, setError] = useState2("");
366
+ const handleClose = useCallback2(() => {
367
+ setDescription("");
368
+ setError("");
369
+ setSubmitted(false);
370
+ onClose();
371
+ }, [onClose]);
372
+ useEffect2(() => {
373
+ if (!isOpen) return;
374
+ const onKey = (e) => {
375
+ if (e.key === "Escape") handleClose();
376
+ };
377
+ document.addEventListener("keydown", onKey);
378
+ return () => document.removeEventListener("keydown", onKey);
379
+ }, [isOpen, handleClose]);
380
+ if (!isOpen) return null;
381
+ const handleSubmit = async (e) => {
382
+ e.preventDefault();
383
+ if (!description.trim()) return;
384
+ setSubmitting(true);
385
+ setError("");
386
+ try {
387
+ const res = await fetch(`${apiBaseUrl}/api/feedback/request`, {
388
+ method: "POST",
389
+ headers: { "Content-Type": "application/json" },
390
+ body: JSON.stringify({ tool_name: toolName, description, user_email: userEmail })
391
+ });
392
+ if (res.ok) {
393
+ setSubmitted(true);
394
+ setTimeout(handleClose, 2e3);
395
+ } else {
396
+ setError("Something went wrong. Please try again.");
397
+ }
398
+ } catch {
399
+ setError("Could not send request. Check your connection.");
400
+ } finally {
401
+ setSubmitting(false);
402
+ }
403
+ };
404
+ return /* @__PURE__ */ jsx6(
405
+ "div",
406
+ {
407
+ className: "fixed inset-0 z-50 flex items-center justify-center p-4",
408
+ style: { background: "rgba(0,12,23,0.85)", backdropFilter: "blur(6px)" },
409
+ onClick: handleClose,
410
+ children: /* @__PURE__ */ jsxs6(
411
+ "div",
412
+ {
413
+ className: "relative glass-card rounded-2xl w-full max-w-md p-8",
414
+ style: { animation: "fadeIn 0.15s ease" },
415
+ onClick: (e) => e.stopPropagation(),
416
+ children: [
417
+ /* @__PURE__ */ jsx6(
418
+ "button",
419
+ {
420
+ onClick: handleClose,
421
+ className: "absolute top-4 right-4 p-2 text-brand/50 hover:text-brand hover:bg-white/5 rounded-lg transition-colors",
422
+ "aria-label": "Close",
423
+ children: /* @__PURE__ */ jsx6("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx6("path", { d: "M18 6L6 18M6 6l12 12" }) })
424
+ }
425
+ ),
426
+ submitted ? /* @__PURE__ */ jsxs6("div", { className: "text-center py-6", children: [
427
+ /* @__PURE__ */ jsx6("div", { className: "w-12 h-12 rounded-full bg-brand/10 flex items-center justify-center mx-auto mb-4", children: /* @__PURE__ */ jsx6("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", className: "text-brand", children: /* @__PURE__ */ jsx6("polyline", { points: "20 6 9 17 4 12" }) }) }),
428
+ /* @__PURE__ */ jsx6("p", { className: "text-white font-semibold", children: "Request received. Thanks!" })
429
+ ] }) : /* @__PURE__ */ jsxs6(Fragment2, { children: [
430
+ /* @__PURE__ */ jsx6("h2", { className: "text-xl font-bold text-white font-serif mb-1", children: "Request a Tool" }),
431
+ /* @__PURE__ */ jsx6("p", { className: "text-brand/50 text-sm mb-6", children: "Have an idea for something we should build?" }),
432
+ /* @__PURE__ */ jsxs6("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
433
+ /* @__PURE__ */ jsxs6("div", { children: [
434
+ /* @__PURE__ */ jsx6("label", { className: "block text-xs font-semibold text-brand/60 uppercase tracking-wider mb-2", children: "Describe what you need" }),
435
+ /* @__PURE__ */ jsx6(
436
+ "textarea",
437
+ {
438
+ value: description,
439
+ onChange: (e) => setDescription(e.target.value),
440
+ placeholder: "What problem would this tool solve? What would it do?",
441
+ rows: 5,
442
+ required: true,
443
+ className: "w-full px-4 py-3 rounded-xl bg-white/5 border border-brand/15 text-white placeholder-brand/30 text-sm resize-none focus:outline-none focus:border-brand/40 transition-colors"
444
+ }
445
+ )
446
+ ] }),
447
+ error && /* @__PURE__ */ jsx6("p", { className: "text-red-400 text-sm", children: error }),
448
+ /* @__PURE__ */ jsx6(
449
+ "button",
450
+ {
451
+ type: "submit",
452
+ disabled: submitting || !description.trim(),
453
+ className: "btn-ice w-full py-3 text-sm font-semibold rounded-xl disabled:opacity-40 disabled:cursor-not-allowed",
454
+ children: submitting ? "Sending..." : "Submit Request"
455
+ }
456
+ )
457
+ ] })
458
+ ] })
459
+ ]
460
+ }
461
+ )
462
+ }
463
+ );
464
+ }
225
465
  export {
226
466
  RCNRFooter_default as RCNRFooter,
227
467
  RCNRHeader_default as RCNRHeader,
228
468
  RCNRMountainLogo_default as RCNRMountainLogo,
229
- RCNRSubNav_default as RCNRSubNav
469
+ RCNRSubNav_default as RCNRSubNav,
470
+ ReportIssueModal,
471
+ RequestToolModal
230
472
  };
231
473
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/RCNRMountainLogo.tsx","../src/RCNRHeader.tsx","../src/RCNRSubNav.tsx","../src/RCNRFooter.tsx"],"sourcesContent":["interface RCNRMountainLogoProps {\r\n href?: string\r\n className?: string\r\n}\r\n\r\nfunction RCNRMountainLogo({\r\n href = 'https://teacher.rcnr.net',\r\n className = '',\r\n}: RCNRMountainLogoProps) {\r\n return (\r\n <a\r\n href={href}\r\n className={`flex items-center justify-center w-10 h-10 rounded-lg bg-brand/10 hover:bg-brand/20 transition-colors ${className}`}\r\n title=\"Back to Dashboard\"\r\n >\r\n <svg\r\n width=\"28\"\r\n height=\"24\"\r\n viewBox=\"0 0 120 100\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <path\r\n d=\"M10,90l26.48-39.76h.31s4.54,5.02,4.54,5.02l.32-.16,23.06-37.14,17.34,28.63,3.65-4.61,30.22,48.03h-8.43c-7.17-12.26-15.51-24.35-23.06-36.26-1.43.52-2.03,3.6-3.49,3.97l-16.31-25.93-21.87,34.36-5.09-5.01-19.48,28.87h-8.19Z\"\r\n fill=\"#99D9D9\"\r\n />\r\n <path\r\n d=\"M89.84,90h-5.73c-6.34-8.18-12.93-16.89-19.64-24.65-6.66,8.19-13.04,16.6-19.89,24.65h-5.81l25.69-39.76,25.37,39.76Z\"\r\n fill=\"#99D9D9\"\r\n />\r\n </svg>\r\n </a>\r\n )\r\n}\r\n\r\nexport default RCNRMountainLogo\r\n","import type { ReactNode } from 'react'\r\nimport type { RCNRHeaderProps } from './types'\r\nimport RCNRMountainLogo from './RCNRMountainLogo'\r\n\r\nfunction NavButton({\r\n onClick,\r\n icon,\r\n label,\r\n title,\r\n}: {\r\n onClick: () => void\r\n icon: ReactNode\r\n label: string\r\n title?: string\r\n}) {\r\n return (\r\n <button\r\n onClick={onClick}\r\n className=\"flex items-center gap-2 px-3 py-2 text-brand/70 hover:text-brand hover:bg-brand/5 rounded-lg transition-colors\"\r\n title={title ?? label}\r\n >\r\n {icon}\r\n <span className=\"hidden md:inline text-sm\">{label}</span>\r\n </button>\r\n )\r\n}\r\n\r\nconst defaultReportIssue = () =>\r\n window.open('mailto:support@rcnr.net?subject=Bug%20Report', '_blank')\r\n\r\nconst defaultRequestTool = () =>\r\n window.open('mailto:support@rcnr.net?subject=Feature%20Request', '_blank')\r\n\r\nfunction RCNRHeader({\r\n toolName,\r\n dashboardUrl = 'https://teacher.rcnr.net',\r\n extraNavItems,\r\n userAvatar,\r\n onHowItWorks,\r\n onReportIssue = defaultReportIssue,\r\n onRequestTool = defaultRequestTool,\r\n}: RCNRHeaderProps) {\r\n return (\r\n <header className=\"glass-card border-b border-brand/15 px-6 py-4\">\r\n <div className=\"flex items-center justify-between\">\r\n {/* Left: Logo + Tool Name */}\r\n <div className=\"flex items-center gap-4\">\r\n <RCNRMountainLogo href={dashboardUrl} />\r\n <span className=\"text-xl font-serif text-brand\">{toolName}</span>\r\n </div>\r\n\r\n {/* Right: Nav Actions */}\r\n <div className=\"flex items-center gap-2\">\r\n {/* Tool-specific nav items first */}\r\n {extraNavItems?.map((item) => (\r\n <NavButton\r\n key={item.label}\r\n onClick={item.onClick}\r\n icon={item.icon}\r\n label={item.label}\r\n />\r\n ))}\r\n\r\n {/* Standard nav items in fixed order */}\r\n {onHowItWorks && (\r\n <NavButton\r\n onClick={onHowItWorks}\r\n label=\"How It Works\"\r\n icon={\r\n <svg\r\n className=\"w-[18px] h-[18px]\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3\"\r\n />\r\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\r\n </svg>\r\n }\r\n />\r\n )}\r\n\r\n <NavButton\r\n onClick={onReportIssue}\r\n label=\"Report Issue\"\r\n icon={\r\n <svg\r\n className=\"w-[18px] h-[18px]\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\r\n />\r\n </svg>\r\n }\r\n />\r\n\r\n <NavButton\r\n onClick={onRequestTool}\r\n label=\"Request Tool\"\r\n icon={\r\n <svg\r\n className=\"w-[18px] h-[18px]\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z\"\r\n />\r\n </svg>\r\n }\r\n />\r\n\r\n {userAvatar}\r\n </div>\r\n </div>\r\n </header>\r\n )\r\n}\r\n\r\nexport default RCNRHeader\r\n","import type { RCNRSubNavProps } from './types'\r\n\r\nfunction RCNRSubNav({ tabs }: RCNRSubNavProps) {\r\n return (\r\n <nav className=\"flex items-center gap-1 px-6 py-2 border-b border-brand/10 bg-surface/50\">\r\n {tabs.map((tab) => {\r\n const isWarning = tab.variant === 'warning'\r\n const activeClass = isWarning\r\n ? 'bg-warning/10 text-warning border border-warning/20'\r\n : 'bg-brand/15 text-brand'\r\n const inactiveClass = isWarning\r\n ? 'text-warning/70 hover:text-warning hover:bg-warning/5 border border-warning/10'\r\n : 'text-brand/50 hover:text-brand hover:bg-brand/5'\r\n\r\n const className = `flex items-center gap-2 px-4 py-2 rounded-lg text-sm transition-colors ${\r\n tab.active ? activeClass : inactiveClass\r\n }`\r\n\r\n if (tab.href) {\r\n return (\r\n <a key={tab.label} href={tab.href} className={className}>\r\n {tab.icon}\r\n <span>{tab.label}</span>\r\n </a>\r\n )\r\n }\r\n\r\n return (\r\n <button\r\n key={tab.label}\r\n onClick={tab.onClick}\r\n className={className}\r\n >\r\n {tab.icon}\r\n <span>{tab.label}</span>\r\n </button>\r\n )\r\n })}\r\n </nav>\r\n )\r\n}\r\n\r\nexport default RCNRSubNav\r\n","import type { RCNRFooterProps } from './types'\r\n\r\nfunction RCNRFooter({\r\n toolName,\r\n linkUrl = 'https://rcnr.net',\r\n}: RCNRFooterProps) {\r\n return (\r\n <footer className=\"mt-auto py-4 text-center text-sm text-brand-dark/50\">\r\n <a\r\n href={linkUrl}\r\n className=\"hover:text-brand transition-colors\"\r\n >\r\n {toolName} — Part of the RCNR Teacher Toolbox\r\n </a>\r\n </footer>\r\n )\r\n}\r\n\r\nexport default RCNRFooter\r\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsxs","jsx","jsxs"]}
1
+ {"version":3,"sources":["../src/RCNRMountainLogo.tsx","../src/RCNRHeader.tsx","../src/RCNRSubNav.tsx","../src/RCNRFooter.tsx","../src/ReportIssueModal.tsx","../src/RequestToolModal.tsx"],"sourcesContent":["interface RCNRMountainLogoProps {\r\n href?: string\r\n className?: string\r\n}\r\n\r\nfunction RCNRMountainLogo({\r\n href = 'https://teacher.rcnr.net',\r\n className = '',\r\n}: RCNRMountainLogoProps) {\r\n return (\r\n <a\r\n href={href}\r\n className={`flex items-center justify-center w-10 h-10 rounded-lg bg-brand/10 hover:bg-brand/20 transition-colors ${className}`}\r\n title=\"Back to Dashboard\"\r\n >\r\n <svg\r\n width=\"28\"\r\n height=\"24\"\r\n viewBox=\"0 0 120 100\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <path\r\n d=\"M10,90l26.48-39.76h.31s4.54,5.02,4.54,5.02l.32-.16,23.06-37.14,17.34,28.63,3.65-4.61,30.22,48.03h-8.43c-7.17-12.26-15.51-24.35-23.06-36.26-1.43.52-2.03,3.6-3.49,3.97l-16.31-25.93-21.87,34.36-5.09-5.01-19.48,28.87h-8.19Z\"\r\n fill=\"#99D9D9\"\r\n />\r\n <path\r\n d=\"M89.84,90h-5.73c-6.34-8.18-12.93-16.89-19.64-24.65-6.66,8.19-13.04,16.6-19.89,24.65h-5.81l25.69-39.76,25.37,39.76Z\"\r\n fill=\"#99D9D9\"\r\n />\r\n </svg>\r\n </a>\r\n )\r\n}\r\n\r\nexport default RCNRMountainLogo\r\n","import type { ReactNode } from 'react'\r\nimport type { RCNRHeaderProps } from './types'\r\nimport RCNRMountainLogo from './RCNRMountainLogo'\r\n\r\nfunction NavButton({\r\n onClick,\r\n icon,\r\n label,\r\n title,\r\n}: {\r\n onClick: () => void\r\n icon: ReactNode\r\n label: string\r\n title?: string\r\n}) {\r\n return (\r\n <button\r\n onClick={onClick}\r\n className=\"flex items-center gap-2 px-3 py-2 text-brand/70 hover:text-brand hover:bg-brand/5 rounded-lg transition-colors\"\r\n title={title ?? label}\r\n >\r\n {icon}\r\n <span className=\"hidden md:inline text-sm\">{label}</span>\r\n </button>\r\n )\r\n}\r\n\r\nconst defaultReportIssue = () =>\r\n window.open('mailto:support@rcnr.net?subject=Bug%20Report', '_blank')\r\n\r\nconst defaultRequestTool = () =>\r\n window.open('mailto:support@rcnr.net?subject=Feature%20Request', '_blank')\r\n\r\nfunction RCNRHeader({\r\n toolName,\r\n dashboardUrl = 'https://teacher.rcnr.net',\r\n extraNavItems,\r\n userAvatar,\r\n onHowItWorks,\r\n onReportIssue = defaultReportIssue,\r\n onRequestTool = defaultRequestTool,\r\n}: RCNRHeaderProps) {\r\n return (\r\n <header className=\"glass-card border-b border-brand/15 px-6 py-4\">\r\n <div className=\"flex items-center justify-between\">\r\n {/* Left: Logo + Tool Name */}\r\n <div className=\"flex items-center gap-4\">\r\n <RCNRMountainLogo href={dashboardUrl} />\r\n <span className=\"text-xl font-serif text-brand\">{toolName}</span>\r\n </div>\r\n\r\n {/* Right: Nav Actions */}\r\n <div className=\"flex items-center gap-2\">\r\n {/* Tool-specific nav items first */}\r\n {extraNavItems?.map((item) => (\r\n <NavButton\r\n key={item.label}\r\n onClick={item.onClick}\r\n icon={item.icon}\r\n label={item.label}\r\n />\r\n ))}\r\n\r\n {/* Standard nav items in fixed order */}\r\n {onHowItWorks && (\r\n <NavButton\r\n onClick={onHowItWorks}\r\n label=\"How It Works\"\r\n icon={\r\n <svg\r\n className=\"w-[18px] h-[18px]\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3\"\r\n />\r\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\r\n </svg>\r\n }\r\n />\r\n )}\r\n\r\n <NavButton\r\n onClick={onReportIssue}\r\n label=\"Report Issue\"\r\n icon={\r\n <svg\r\n className=\"w-[18px] h-[18px]\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\r\n />\r\n </svg>\r\n }\r\n />\r\n\r\n <NavButton\r\n onClick={onRequestTool}\r\n label=\"Request Tool\"\r\n icon={\r\n <svg\r\n className=\"w-[18px] h-[18px]\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z\"\r\n />\r\n </svg>\r\n }\r\n />\r\n\r\n {userAvatar}\r\n </div>\r\n </div>\r\n </header>\r\n )\r\n}\r\n\r\nexport default RCNRHeader\r\n","import type { RCNRSubNavProps } from './types'\r\n\r\nfunction RCNRSubNav({ tabs }: RCNRSubNavProps) {\r\n return (\r\n <nav className=\"flex items-center gap-1 px-6 py-2 border-b border-brand/10 bg-surface/50\">\r\n {tabs.map((tab) => {\r\n const isWarning = tab.variant === 'warning'\r\n const activeClass = isWarning\r\n ? 'bg-warning/10 text-warning border border-warning/20'\r\n : 'bg-brand/15 text-brand'\r\n const inactiveClass = isWarning\r\n ? 'text-warning/70 hover:text-warning hover:bg-warning/5 border border-warning/10'\r\n : 'text-brand/50 hover:text-brand hover:bg-brand/5'\r\n\r\n const className = `flex items-center gap-2 px-4 py-2 rounded-lg text-sm transition-colors ${\r\n tab.active ? activeClass : inactiveClass\r\n }`\r\n\r\n if (tab.href) {\r\n return (\r\n <a key={tab.label} href={tab.href} className={className}>\r\n {tab.icon}\r\n <span>{tab.label}</span>\r\n </a>\r\n )\r\n }\r\n\r\n return (\r\n <button\r\n key={tab.label}\r\n onClick={tab.onClick}\r\n className={className}\r\n >\r\n {tab.icon}\r\n <span>{tab.label}</span>\r\n </button>\r\n )\r\n })}\r\n </nav>\r\n )\r\n}\r\n\r\nexport default RCNRSubNav\r\n","import type { RCNRFooterProps } from './types'\r\n\r\nfunction RCNRFooter({\r\n toolName,\r\n linkUrl = 'https://rcnr.net',\r\n}: RCNRFooterProps) {\r\n return (\r\n <footer className=\"mt-auto py-4 text-center text-sm text-brand-dark/50\">\r\n <a\r\n href={linkUrl}\r\n className=\"hover:text-brand transition-colors\"\r\n >\r\n {toolName} — Part of the RCNR Teacher Toolbox\r\n </a>\r\n </footer>\r\n )\r\n}\r\n\r\nexport default RCNRFooter\r\n","import { useState, useEffect, useCallback } from 'react'\n\ninterface ReportIssueModalProps {\n isOpen: boolean\n onClose: () => void\n toolName: string\n apiBaseUrl?: string\n userEmail?: string\n}\n\nexport function ReportIssueModal({\n isOpen,\n onClose,\n toolName,\n apiBaseUrl = 'https://api.rcnr.net',\n userEmail,\n}: ReportIssueModalProps) {\n const [description, setDescription] = useState('')\n const [submitting, setSubmitting] = useState(false)\n const [submitted, setSubmitted] = useState(false)\n const [error, setError] = useState('')\n\n const handleClose = useCallback(() => {\n setDescription('')\n setError('')\n setSubmitted(false)\n onClose()\n }, [onClose])\n\n useEffect(() => {\n if (!isOpen) return\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') handleClose() }\n document.addEventListener('keydown', onKey)\n return () => document.removeEventListener('keydown', onKey)\n }, [isOpen, handleClose])\n\n if (!isOpen) return null\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n if (!description.trim()) return\n setSubmitting(true)\n setError('')\n try {\n const res = await fetch(`${apiBaseUrl}/api/feedback/report`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ tool_name: toolName, description, user_email: userEmail }),\n })\n if (res.ok) {\n setSubmitted(true)\n setTimeout(handleClose, 2000)\n } else {\n setError('Something went wrong. Please try again.')\n }\n } catch {\n setError('Could not send report. Check your connection.')\n } finally {\n setSubmitting(false)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center p-4\"\n style={{ background: 'rgba(0,12,23,0.85)', backdropFilter: 'blur(6px)' }}\n onClick={handleClose}\n >\n <div\n className=\"relative glass-card rounded-2xl w-full max-w-md p-8\"\n style={{ animation: 'fadeIn 0.15s ease' }}\n onClick={(e) => e.stopPropagation()}\n >\n <button\n onClick={handleClose}\n className=\"absolute top-4 right-4 p-2 text-brand/50 hover:text-brand hover:bg-white/5 rounded-lg transition-colors\"\n aria-label=\"Close\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n </button>\n\n {submitted ? (\n <div className=\"text-center py-6\">\n <div className=\"w-12 h-12 rounded-full bg-emerald-500/15 flex items-center justify-center mx-auto mb-4\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" className=\"text-emerald-400\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </div>\n <p className=\"text-white font-semibold\">Report sent. We'll fix it fast.</p>\n </div>\n ) : (\n <>\n <h2 className=\"text-xl font-bold text-white font-serif mb-1\">Report an Issue</h2>\n <p className=\"text-brand/50 text-sm mb-6\">Found a bug or something broken? Let us know.</p>\n\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <div>\n <label className=\"block text-xs font-semibold text-brand/60 uppercase tracking-wider mb-2\">Tool</label>\n <input\n type=\"text\"\n value={toolName}\n disabled\n className=\"w-full px-4 py-2.5 rounded-xl bg-white/5 border border-brand/10 text-brand/40 text-sm\"\n />\n </div>\n\n <div>\n <label className=\"block text-xs font-semibold text-brand/60 uppercase tracking-wider mb-2\">\n What went wrong?\n </label>\n <textarea\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Describe the issue...\"\n rows={4}\n required\n className=\"w-full px-4 py-3 rounded-xl bg-white/5 border border-brand/15 text-white placeholder-brand/30 text-sm resize-none focus:outline-none focus:border-brand/40 transition-colors\"\n />\n </div>\n\n {error && <p className=\"text-red-400 text-sm\">{error}</p>}\n\n <button\n type=\"submit\"\n disabled={submitting || !description.trim()}\n className=\"btn-ice w-full py-3 text-sm font-semibold rounded-xl disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n {submitting ? 'Sending...' : 'Submit Report'}\n </button>\n </form>\n </>\n )}\n </div>\n </div>\n )\n}\n","import { useState, useEffect, useCallback } from 'react'\n\ninterface RequestToolModalProps {\n isOpen: boolean\n onClose: () => void\n toolName: string\n apiBaseUrl?: string\n userEmail?: string\n}\n\nexport function RequestToolModal({\n isOpen,\n onClose,\n toolName,\n apiBaseUrl = 'https://api.rcnr.net',\n userEmail,\n}: RequestToolModalProps) {\n const [description, setDescription] = useState('')\n const [submitting, setSubmitting] = useState(false)\n const [submitted, setSubmitted] = useState(false)\n const [error, setError] = useState('')\n\n const handleClose = useCallback(() => {\n setDescription('')\n setError('')\n setSubmitted(false)\n onClose()\n }, [onClose])\n\n useEffect(() => {\n if (!isOpen) return\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') handleClose() }\n document.addEventListener('keydown', onKey)\n return () => document.removeEventListener('keydown', onKey)\n }, [isOpen, handleClose])\n\n if (!isOpen) return null\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n if (!description.trim()) return\n setSubmitting(true)\n setError('')\n try {\n const res = await fetch(`${apiBaseUrl}/api/feedback/request`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ tool_name: toolName, description, user_email: userEmail }),\n })\n if (res.ok) {\n setSubmitted(true)\n setTimeout(handleClose, 2000)\n } else {\n setError('Something went wrong. Please try again.')\n }\n } catch {\n setError('Could not send request. Check your connection.')\n } finally {\n setSubmitting(false)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center p-4\"\n style={{ background: 'rgba(0,12,23,0.85)', backdropFilter: 'blur(6px)' }}\n onClick={handleClose}\n >\n <div\n className=\"relative glass-card rounded-2xl w-full max-w-md p-8\"\n style={{ animation: 'fadeIn 0.15s ease' }}\n onClick={(e) => e.stopPropagation()}\n >\n <button\n onClick={handleClose}\n className=\"absolute top-4 right-4 p-2 text-brand/50 hover:text-brand hover:bg-white/5 rounded-lg transition-colors\"\n aria-label=\"Close\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n </button>\n\n {submitted ? (\n <div className=\"text-center py-6\">\n <div className=\"w-12 h-12 rounded-full bg-brand/10 flex items-center justify-center mx-auto mb-4\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" className=\"text-brand\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </div>\n <p className=\"text-white font-semibold\">Request received. Thanks!</p>\n </div>\n ) : (\n <>\n <h2 className=\"text-xl font-bold text-white font-serif mb-1\">Request a Tool</h2>\n <p className=\"text-brand/50 text-sm mb-6\">Have an idea for something we should build?</p>\n\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <div>\n <label className=\"block text-xs font-semibold text-brand/60 uppercase tracking-wider mb-2\">\n Describe what you need\n </label>\n <textarea\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"What problem would this tool solve? What would it do?\"\n rows={5}\n required\n className=\"w-full px-4 py-3 rounded-xl bg-white/5 border border-brand/15 text-white placeholder-brand/30 text-sm resize-none focus:outline-none focus:border-brand/40 transition-colors\"\n />\n </div>\n\n {error && <p className=\"text-red-400 text-sm\">{error}</p>}\n\n <button\n type=\"submit\"\n disabled={submitting || !description.trim()}\n className=\"btn-ice w-full py-3 text-sm font-semibold rounded-xl disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n {submitting ? 'Sending...' : 'Submit Request'}\n </button>\n </form>\n </>\n )}\n </div>\n </div>\n )\n}\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","useState","useEffect","useCallback","Fragment","jsx","jsxs"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rcnr/theme",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "RCNR design system: CSS tokens, shared React components (header, footer, subnav), glass cards, buttons, grid",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",