@appgram/react 0.1.0 → 0.1.3

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.
Files changed (39) hide show
  1. package/dist/{useVote-CLhkwtLT.d.mts → StatusBoard-DhKRu-An.d.mts} +125 -1
  2. package/dist/{useVote-CLhkwtLT.d.ts → StatusBoard-DhKRu-An.d.ts} +125 -1
  3. package/dist/{chunk-N6PJDQCU.mjs → chunk-NABMGLTY.mjs} +210 -6
  4. package/dist/chunk-NABMGLTY.mjs.map +1 -0
  5. package/dist/chunk-NSV6Q6QQ.js +202 -0
  6. package/dist/chunk-NSV6Q6QQ.js.map +1 -0
  7. package/dist/chunk-ONZ7RQBM.mjs +199 -0
  8. package/dist/chunk-ONZ7RQBM.mjs.map +1 -0
  9. package/dist/{chunk-75P634IK.js → chunk-UPTP7QX5.js} +213 -5
  10. package/dist/chunk-UPTP7QX5.js.map +1 -0
  11. package/dist/{chunk-AIDLOCVJ.mjs → chunk-UWIJR4ZY.mjs} +760 -15
  12. package/dist/chunk-UWIJR4ZY.mjs.map +1 -0
  13. package/dist/{chunk-3UBJGXCO.js → chunk-WZIN7KEM.js} +820 -74
  14. package/dist/chunk-WZIN7KEM.js.map +1 -0
  15. package/dist/components/index.d.mts +68 -106
  16. package/dist/components/index.d.ts +68 -106
  17. package/dist/components/index.js +29 -21
  18. package/dist/components/index.mjs +2 -2
  19. package/dist/hooks/index.d.mts +3 -572
  20. package/dist/hooks/index.d.ts +3 -572
  21. package/dist/hooks/index.js +33 -13
  22. package/dist/hooks/index.mjs +2 -2
  23. package/dist/index-DpZz_TZE.d.ts +917 -0
  24. package/dist/index-X95JANOa.d.mts +917 -0
  25. package/dist/index.d.mts +32 -5
  26. package/dist/index.d.ts +32 -5
  27. package/dist/index.js +123 -76
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +60 -41
  30. package/dist/index.mjs.map +1 -1
  31. package/package.json +2 -2
  32. package/dist/chunk-3UBJGXCO.js.map +0 -1
  33. package/dist/chunk-75P634IK.js.map +0 -1
  34. package/dist/chunk-AIDLOCVJ.mjs.map +0 -1
  35. package/dist/chunk-KPIKYXAN.mjs +0 -47
  36. package/dist/chunk-KPIKYXAN.mjs.map +0 -1
  37. package/dist/chunk-N6PJDQCU.mjs.map +0 -1
  38. package/dist/chunk-ZJZ3A2S3.js +0 -49
  39. package/dist/chunk-ZJZ3A2S3.js.map +0 -1
@@ -1,11 +1,10 @@
1
- import { useAppgramContext, useVote, cn, useWishes, useComments, useRoadmap, useReleases, useRelease, useHelpCenter, useHelpFlow, useHelpArticle, useSupport } from './chunk-N6PJDQCU.mjs';
1
+ import { useAppgramContext, useVote, cn, useWishes, useComments, useRoadmap, useReleases, useRelease, useHelpCenter, useHelpFlow, useHelpArticle, useSupport, useSurvey, useSurveySubmit, getFingerprint, useContactForm, useContactFormSubmit } from './chunk-NABMGLTY.mjs';
2
2
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
3
  import { motion, AnimatePresence } from 'framer-motion';
4
4
  import { ChevronUp, MessageSquare, Plus, Search, Sparkles, AlertCircle, CheckCircle2, Clock, X, User, Loader2, Send, Package, ArrowLeft, Tag, Calendar, Wrench, Bug, Zap, Gift, ChevronRight, Mail, MessageCircle, HelpCircle, Folder, BookOpen, FileText, Upload, XCircle, AlertTriangle, ArrowRight, Activity, ChevronLeft, Pause, Play } from 'lucide-react';
5
- import React12, { useState, useEffect, useCallback, useRef } from 'react';
5
+ import React12, { useState, useEffect, useCallback, useRef, useMemo } from 'react';
6
6
  import ReactMarkdown from 'react-markdown';
7
7
  import remarkGfm from 'remark-gfm';
8
- import DOMPurify from 'dompurify';
9
8
 
10
9
  var sizeClasses = {
11
10
  sm: "px-2 py-1 text-xs min-w-[50px]",
@@ -953,7 +952,6 @@ function WishDetail({
953
952
  placeholder: "Your name (optional)",
954
953
  value: authorName,
955
954
  onChange: (e) => setAuthorName(e.target.value),
956
- maxLength: 100,
957
955
  className: "w-full h-10 px-4 text-sm border focus:outline-none focus:ring-2 transition-all",
958
956
  style: {
959
957
  borderColor: isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)",
@@ -970,7 +968,6 @@ function WishDetail({
970
968
  placeholder: "Write a comment...",
971
969
  value: newComment,
972
970
  onChange: (e) => setNewComment(e.target.value),
973
- maxLength: 1e3,
974
971
  className: "flex-1 min-h-[60px] px-4 py-3 text-sm border focus:outline-none focus:ring-2 resize-none transition-all",
975
972
  style: {
976
973
  borderColor: isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)",
@@ -1163,7 +1160,6 @@ function SubmitWishForm({
1163
1160
  value: formData.title,
1164
1161
  onChange: (e) => setFormData({ ...formData, title: e.target.value }),
1165
1162
  required: true,
1166
- maxLength: 150,
1167
1163
  className: "w-full h-11 px-4 text-sm border focus:outline-none focus:ring-2 transition-all",
1168
1164
  style: {
1169
1165
  borderColor: isDark ? "rgba(255, 255, 255, 0.15)" : "rgba(0, 0, 0, 0.15)",
@@ -1217,7 +1213,6 @@ function SubmitWishForm({
1217
1213
  value: formData.description,
1218
1214
  onChange: (e) => setFormData({ ...formData, description: e.target.value }),
1219
1215
  required: true,
1220
- maxLength: 500,
1221
1216
  rows: 5,
1222
1217
  className: "w-full px-4 py-3 text-sm border focus:outline-none focus:ring-2 resize-none transition-all",
1223
1218
  style: {
@@ -2941,7 +2936,6 @@ function MediaCarousel({
2941
2936
  {
2942
2937
  src: getEmbedUrl(currentMedia.url),
2943
2938
  className: "w-full h-full",
2944
- sandbox: "allow-scripts allow-same-origin allow-presentation",
2945
2939
  allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
2946
2940
  allowFullScreen: true,
2947
2941
  title: currentMedia.title || "Video"
@@ -4330,7 +4324,7 @@ function HelpArticleDetail({
4330
4324
  "div",
4331
4325
  {
4332
4326
  className: "article-content",
4333
- dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(article.content) }
4327
+ dangerouslySetInnerHTML: { __html: article.content }
4334
4328
  }
4335
4329
  )
4336
4330
  }
@@ -4882,7 +4876,6 @@ function SupportForm({
4882
4876
  placeholder: "Your name",
4883
4877
  value: formData.user_name,
4884
4878
  onChange: handleChange,
4885
- maxLength: 100,
4886
4879
  className: "w-full h-10 px-4 text-sm border focus:outline-none focus:ring-2 transition-all",
4887
4880
  style: {
4888
4881
  backgroundColor: isDark ? "var(--appgram-card)" : "white",
@@ -4950,7 +4943,6 @@ function SupportForm({
4950
4943
  value: formData.subject,
4951
4944
  onChange: handleChange,
4952
4945
  required: true,
4953
- maxLength: 200,
4954
4946
  className: "w-full h-10 px-4 text-sm border focus:outline-none focus:ring-2 transition-all",
4955
4947
  style: {
4956
4948
  backgroundColor: isDark ? "var(--appgram-card)" : "white",
@@ -4974,7 +4966,6 @@ function SupportForm({
4974
4966
  value: formData.description,
4975
4967
  onChange: handleChange,
4976
4968
  required: true,
4977
- maxLength: 2e3,
4978
4969
  rows: 5,
4979
4970
  className: "w-full px-4 py-3 text-sm border focus:outline-none focus:ring-2 resize-none transition-all",
4980
4971
  style: {
@@ -6335,7 +6326,761 @@ function StatusIncidentDetail({
6335
6326
  )
6336
6327
  ] }) });
6337
6328
  }
6329
+ function SurveyRenderer({
6330
+ slug,
6331
+ title,
6332
+ description,
6333
+ onComplete,
6334
+ onError,
6335
+ externalUserId,
6336
+ metadata,
6337
+ className
6338
+ }) {
6339
+ const { theme } = useAppgramContext();
6340
+ const { survey, nodes, isLoading, error: fetchError } = useSurvey(slug);
6341
+ const { submitResponse, isSubmitting, error: submitError, successMessage } = useSurveySubmit({
6342
+ onSuccess: () => onComplete?.(),
6343
+ onError
6344
+ });
6345
+ const [answers, setAnswers] = useState(/* @__PURE__ */ new Map());
6346
+ const [visitedNodes, setVisitedNodes] = useState([]);
6347
+ const primaryColor = theme.colors?.primary || "#0EA5E9";
6348
+ const borderRadius = theme.borderRadius || 16;
6349
+ const isDark = theme.isDark ?? false;
6350
+ const sortedNodes = useMemo(() => {
6351
+ return [...nodes].sort((a, b) => a.sort_order - b.sort_order);
6352
+ }, [nodes]);
6353
+ const rootNode = useMemo(() => {
6354
+ return sortedNodes.find((n) => n.parent_id === null) || sortedNodes[0];
6355
+ }, [sortedNodes]);
6356
+ const currentNodeId = visitedNodes.length > 0 ? visitedNodes[visitedNodes.length - 1] : rootNode?.id;
6357
+ const currentNode = nodes.find((n) => n.id === currentNodeId) || null;
6358
+ const getNextNode = useCallback((node, answer) => {
6359
+ if (node.question_type === "yes_no") {
6360
+ const isYes = answer.answer_text === "yes" || answer.answer === true;
6361
+ const nextId = isYes ? node.answer_yes_node_id : node.answer_no_node_id;
6362
+ if (nextId) {
6363
+ return nodes.find((n) => n.id === nextId) || null;
6364
+ }
6365
+ }
6366
+ if (node.branches && node.branches.length > 0) {
6367
+ for (const branch of node.branches) {
6368
+ const { condition } = branch;
6369
+ let matches = false;
6370
+ if (condition.type === "equals") {
6371
+ if (answer.answer_text !== void 0) matches = answer.answer_text === String(condition.value);
6372
+ if (answer.answer_rating !== void 0) matches = answer.answer_rating === Number(condition.value);
6373
+ if (answer.answer_options?.length === 1) matches = answer.answer_options[0] === String(condition.value);
6374
+ } else if (condition.type === "contains") {
6375
+ if (answer.answer_text) matches = answer.answer_text.includes(String(condition.value));
6376
+ if (answer.answer_options) matches = answer.answer_options.includes(String(condition.value));
6377
+ } else if (condition.type === "gt" && answer.answer_rating !== void 0) {
6378
+ matches = answer.answer_rating > Number(condition.value);
6379
+ } else if (condition.type === "lt" && answer.answer_rating !== void 0) {
6380
+ matches = answer.answer_rating < Number(condition.value);
6381
+ } else if (condition.type === "gte" && answer.answer_rating !== void 0) {
6382
+ matches = answer.answer_rating >= Number(condition.value);
6383
+ } else if (condition.type === "lte" && answer.answer_rating !== void 0) {
6384
+ matches = answer.answer_rating <= Number(condition.value);
6385
+ }
6386
+ if (matches) {
6387
+ return nodes.find((n) => n.id === branch.next_node_id) || null;
6388
+ }
6389
+ }
6390
+ }
6391
+ if (node.next_node_id) {
6392
+ return nodes.find((n) => n.id === node.next_node_id) || null;
6393
+ }
6394
+ return null;
6395
+ }, [nodes]);
6396
+ const handleNext = useCallback(() => {
6397
+ if (!currentNode) return;
6398
+ const answer = answers.get(currentNode.id);
6399
+ if (!answer && currentNode.is_required) return;
6400
+ const nextNode = answer ? getNextNode(currentNode, answer) : null;
6401
+ if (nextNode) {
6402
+ setVisitedNodes((prev) => [...prev, nextNode.id]);
6403
+ } else {
6404
+ handleSubmit();
6405
+ }
6406
+ }, [currentNode, answers, getNextNode]);
6407
+ const handleBack = useCallback(() => {
6408
+ setVisitedNodes((prev) => prev.slice(0, -1));
6409
+ }, []);
6410
+ const handleSubmit = useCallback(async () => {
6411
+ if (!survey) return;
6412
+ const fingerprint = getFingerprint();
6413
+ const answerEntries = Array.from(answers.entries()).map(([nodeId, ans]) => ({
6414
+ node_id: nodeId,
6415
+ answer: ans.answer,
6416
+ answer_text: ans.answer_text,
6417
+ answer_options: ans.answer_options,
6418
+ answer_rating: ans.answer_rating
6419
+ }));
6420
+ await submitResponse(survey.id, {
6421
+ fingerprint,
6422
+ external_user_id: externalUserId,
6423
+ metadata,
6424
+ answers: answerEntries
6425
+ });
6426
+ }, [survey, answers, submitResponse, externalUserId, metadata]);
6427
+ const updateAnswer = useCallback((nodeId, answer) => {
6428
+ setAnswers((prev) => {
6429
+ const next = new Map(prev);
6430
+ next.set(nodeId, answer);
6431
+ return next;
6432
+ });
6433
+ }, []);
6434
+ if (currentNode?.result_message) {
6435
+ return /* @__PURE__ */ jsx("div", { className: cn("max-w-2xl mx-auto", className), children: /* @__PURE__ */ jsx(
6436
+ "div",
6437
+ {
6438
+ className: "rounded-lg border p-8 text-center",
6439
+ style: {
6440
+ backgroundColor: isDark ? "var(--appgram-card)" : "rgba(255, 255, 255, 0.7)",
6441
+ borderColor: isDark ? "rgba(255, 255, 255, 0.05)" : "rgba(0, 0, 0, 0.05)",
6442
+ borderRadius: `${Math.min(borderRadius, 12)}px`
6443
+ },
6444
+ children: /* @__PURE__ */ jsx(
6445
+ "p",
6446
+ {
6447
+ className: "text-lg font-medium",
6448
+ style: { color: "var(--appgram-foreground)" },
6449
+ children: currentNode.result_message
6450
+ }
6451
+ )
6452
+ }
6453
+ ) });
6454
+ }
6455
+ if (successMessage) {
6456
+ return /* @__PURE__ */ jsx("div", { className: cn("max-w-2xl mx-auto", className), children: /* @__PURE__ */ jsxs(
6457
+ "div",
6458
+ {
6459
+ className: "rounded-lg border p-8 text-center",
6460
+ style: {
6461
+ backgroundColor: isDark ? "var(--appgram-card)" : "rgba(255, 255, 255, 0.7)",
6462
+ borderColor: isDark ? "rgba(255, 255, 255, 0.05)" : "rgba(0, 0, 0, 0.05)",
6463
+ borderRadius: `${Math.min(borderRadius, 12)}px`
6464
+ },
6465
+ children: [
6466
+ /* @__PURE__ */ jsx(
6467
+ "div",
6468
+ {
6469
+ className: "inline-flex items-center justify-center w-16 h-16 rounded-full mb-6",
6470
+ style: { backgroundColor: "#10b98115" },
6471
+ children: /* @__PURE__ */ jsx("svg", { className: "w-8 h-8", style: { color: "#10b981" }, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) })
6472
+ }
6473
+ ),
6474
+ /* @__PURE__ */ jsx(
6475
+ "h2",
6476
+ {
6477
+ className: "text-2xl font-bold mb-3",
6478
+ style: { color: "var(--appgram-foreground)" },
6479
+ children: "Thank You"
6480
+ }
6481
+ ),
6482
+ /* @__PURE__ */ jsx(
6483
+ "p",
6484
+ {
6485
+ className: "text-base",
6486
+ style: { color: isDark ? "rgba(255, 255, 255, 0.6)" : "rgba(0, 0, 0, 0.6)" },
6487
+ children: successMessage
6488
+ }
6489
+ )
6490
+ ]
6491
+ }
6492
+ ) });
6493
+ }
6494
+ if (isLoading) {
6495
+ return /* @__PURE__ */ jsx("div", { className: cn("max-w-2xl mx-auto flex items-center justify-center py-12", className), children: /* @__PURE__ */ jsx(
6496
+ "div",
6497
+ {
6498
+ className: "w-8 h-8 border-2 border-t-transparent rounded-full animate-spin",
6499
+ style: { borderColor: primaryColor, borderTopColor: "transparent" }
6500
+ }
6501
+ ) });
6502
+ }
6503
+ if (fetchError || submitError) {
6504
+ return /* @__PURE__ */ jsx("div", { className: cn("max-w-2xl mx-auto", className), children: /* @__PURE__ */ jsx(
6505
+ "div",
6506
+ {
6507
+ className: "p-4 text-sm",
6508
+ style: {
6509
+ backgroundColor: "rgba(239, 68, 68, 0.1)",
6510
+ color: "#dc2626",
6511
+ borderRadius: `${Math.min(borderRadius, 8)}px`
6512
+ },
6513
+ children: fetchError || submitError
6514
+ }
6515
+ ) });
6516
+ }
6517
+ if (!currentNode || !survey) return /* @__PURE__ */ jsx("div", {});
6518
+ const currentAnswer = answers.get(currentNode.id);
6519
+ const isAnswered = !!currentAnswer;
6520
+ const isRequired = currentNode.is_required !== false;
6521
+ const canProceed = !isRequired || isAnswered;
6522
+ return /* @__PURE__ */ jsxs("div", { className: cn("max-w-2xl mx-auto", className), children: [
6523
+ (title || survey.name) && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
6524
+ /* @__PURE__ */ jsx(
6525
+ "h1",
6526
+ {
6527
+ className: "text-2xl font-bold mb-2",
6528
+ style: { color: "var(--appgram-foreground)" },
6529
+ children: title || survey.name
6530
+ }
6531
+ ),
6532
+ (description || survey.description) && /* @__PURE__ */ jsx(
6533
+ "p",
6534
+ {
6535
+ className: "text-base",
6536
+ style: { color: isDark ? "rgba(255, 255, 255, 0.6)" : "rgba(0, 0, 0, 0.6)" },
6537
+ children: description || survey.description
6538
+ }
6539
+ )
6540
+ ] }),
6541
+ /* @__PURE__ */ jsxs(
6542
+ "div",
6543
+ {
6544
+ className: "rounded-lg border p-6",
6545
+ style: {
6546
+ backgroundColor: isDark ? "var(--appgram-card)" : "rgba(255, 255, 255, 0.7)",
6547
+ borderColor: isDark ? "rgba(255, 255, 255, 0.05)" : "rgba(0, 0, 0, 0.05)",
6548
+ borderRadius: `${Math.min(borderRadius, 12)}px`
6549
+ },
6550
+ children: [
6551
+ /* @__PURE__ */ jsxs(
6552
+ "h2",
6553
+ {
6554
+ className: "text-lg font-semibold mb-6",
6555
+ style: { color: "var(--appgram-foreground)" },
6556
+ children: [
6557
+ currentNode.question,
6558
+ isRequired && /* @__PURE__ */ jsx("span", { style: { color: "#dc2626" }, children: " *" })
6559
+ ]
6560
+ }
6561
+ ),
6562
+ /* @__PURE__ */ jsx(
6563
+ QuestionInput,
6564
+ {
6565
+ node: currentNode,
6566
+ answer: currentAnswer,
6567
+ onChange: (answer) => updateAnswer(currentNode.id, answer),
6568
+ primaryColor,
6569
+ borderRadius,
6570
+ isDark
6571
+ }
6572
+ ),
6573
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mt-8 pt-6 border-t", style: { borderColor: isDark ? "rgba(255, 255, 255, 0.05)" : "rgba(0, 0, 0, 0.05)" }, children: [
6574
+ /* @__PURE__ */ jsx(
6575
+ "button",
6576
+ {
6577
+ onClick: handleBack,
6578
+ disabled: visitedNodes.length === 0,
6579
+ className: "px-4 py-2 text-sm font-medium transition-opacity disabled:opacity-30",
6580
+ style: { color: isDark ? "rgba(255, 255, 255, 0.6)" : "rgba(0, 0, 0, 0.6)" },
6581
+ children: "Back"
6582
+ }
6583
+ ),
6584
+ /* @__PURE__ */ jsx(
6585
+ "button",
6586
+ {
6587
+ onClick: handleNext,
6588
+ disabled: !canProceed || isSubmitting,
6589
+ className: "px-6 py-2.5 text-sm text-white font-medium transition-all hover:shadow-lg disabled:opacity-50",
6590
+ style: {
6591
+ backgroundColor: primaryColor,
6592
+ borderRadius: `${Math.min(borderRadius, 8)}px`
6593
+ },
6594
+ children: isSubmitting ? "Submitting..." : "Next"
6595
+ }
6596
+ )
6597
+ ] })
6598
+ ]
6599
+ }
6600
+ )
6601
+ ] });
6602
+ }
6603
+ function QuestionInput({
6604
+ node,
6605
+ answer,
6606
+ onChange,
6607
+ primaryColor,
6608
+ borderRadius,
6609
+ isDark
6610
+ }) {
6611
+ switch (node.question_type) {
6612
+ case "yes_no":
6613
+ return /* @__PURE__ */ jsx("div", { className: "flex gap-3", children: ["yes", "no"].map((value) => /* @__PURE__ */ jsx(
6614
+ "button",
6615
+ {
6616
+ onClick: () => onChange({ answer_text: value, answer: value === "yes" }),
6617
+ className: "flex-1 py-3 text-sm font-medium border transition-all",
6618
+ style: {
6619
+ backgroundColor: answer?.answer_text === value ? `${primaryColor}15` : "transparent",
6620
+ borderColor: answer?.answer_text === value ? primaryColor : isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)",
6621
+ color: answer?.answer_text === value ? primaryColor : "var(--appgram-foreground)",
6622
+ borderRadius: `${Math.min(borderRadius, 8)}px`
6623
+ },
6624
+ children: value.charAt(0).toUpperCase() + value.slice(1)
6625
+ },
6626
+ value
6627
+ )) });
6628
+ case "short_answer":
6629
+ return /* @__PURE__ */ jsx(
6630
+ "input",
6631
+ {
6632
+ type: "text",
6633
+ value: answer?.answer_text || "",
6634
+ onChange: (e) => onChange({ answer_text: e.target.value }),
6635
+ placeholder: "Type your answer...",
6636
+ className: "w-full h-10 px-4 text-sm border focus:outline-none focus:ring-2 transition-all",
6637
+ style: {
6638
+ backgroundColor: isDark ? "var(--appgram-card)" : "white",
6639
+ borderColor: isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)",
6640
+ color: "var(--appgram-foreground)",
6641
+ borderRadius: `${Math.min(borderRadius, 8)}px`
6642
+ }
6643
+ }
6644
+ );
6645
+ case "paragraph":
6646
+ return /* @__PURE__ */ jsx(
6647
+ "textarea",
6648
+ {
6649
+ value: answer?.answer_text || "",
6650
+ onChange: (e) => onChange({ answer_text: e.target.value }),
6651
+ placeholder: "Type your answer...",
6652
+ rows: 4,
6653
+ className: "w-full px-4 py-3 text-sm border focus:outline-none focus:ring-2 resize-none transition-all",
6654
+ style: {
6655
+ backgroundColor: isDark ? "var(--appgram-card)" : "white",
6656
+ borderColor: isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)",
6657
+ color: "var(--appgram-foreground)",
6658
+ borderRadius: `${Math.min(borderRadius, 8)}px`
6659
+ }
6660
+ }
6661
+ );
6662
+ case "multiple_choice":
6663
+ return /* @__PURE__ */ jsx("div", { className: "space-y-2", children: (node.options || []).map((option) => /* @__PURE__ */ jsx(
6664
+ "button",
6665
+ {
6666
+ onClick: () => onChange({ answer_options: [option.value] }),
6667
+ className: "w-full text-left px-4 py-3 text-sm border transition-all",
6668
+ style: {
6669
+ backgroundColor: answer?.answer_options?.[0] === option.value ? `${primaryColor}15` : "transparent",
6670
+ borderColor: answer?.answer_options?.[0] === option.value ? primaryColor : isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)",
6671
+ color: "var(--appgram-foreground)",
6672
+ borderRadius: `${Math.min(borderRadius, 8)}px`
6673
+ },
6674
+ children: option.label
6675
+ },
6676
+ option.value
6677
+ )) });
6678
+ case "checkboxes":
6679
+ return /* @__PURE__ */ jsx("div", { className: "space-y-2", children: (node.options || []).map((option) => {
6680
+ const selected = answer?.answer_options?.includes(option.value) || false;
6681
+ return /* @__PURE__ */ jsxs(
6682
+ "button",
6683
+ {
6684
+ onClick: () => {
6685
+ const current = answer?.answer_options || [];
6686
+ const next = selected ? current.filter((v) => v !== option.value) : [...current, option.value];
6687
+ onChange({ answer_options: next });
6688
+ },
6689
+ className: "w-full text-left px-4 py-3 text-sm border transition-all flex items-center gap-3",
6690
+ style: {
6691
+ backgroundColor: selected ? `${primaryColor}15` : "transparent",
6692
+ borderColor: selected ? primaryColor : isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)",
6693
+ color: "var(--appgram-foreground)",
6694
+ borderRadius: `${Math.min(borderRadius, 8)}px`
6695
+ },
6696
+ children: [
6697
+ /* @__PURE__ */ jsx(
6698
+ "div",
6699
+ {
6700
+ className: "w-4 h-4 border rounded flex items-center justify-center shrink-0",
6701
+ style: {
6702
+ borderColor: selected ? primaryColor : isDark ? "rgba(255, 255, 255, 0.3)" : "rgba(0, 0, 0, 0.3)",
6703
+ backgroundColor: selected ? primaryColor : "transparent"
6704
+ },
6705
+ children: selected && /* @__PURE__ */ jsx("svg", { className: "w-3 h-3 text-white", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 3, d: "M5 13l4 4L19 7" }) })
6706
+ }
6707
+ ),
6708
+ option.label
6709
+ ]
6710
+ },
6711
+ option.value
6712
+ );
6713
+ }) });
6714
+ case "rating": {
6715
+ const min = node.min_rating ?? 1;
6716
+ const max = node.max_rating ?? 5;
6717
+ const ratings = Array.from({ length: max - min + 1 }, (_, i) => min + i);
6718
+ return /* @__PURE__ */ jsx("div", { className: "flex gap-2 justify-center", children: ratings.map((value) => /* @__PURE__ */ jsx(
6719
+ "button",
6720
+ {
6721
+ onClick: () => onChange({ answer_rating: value }),
6722
+ className: "w-12 h-12 text-sm font-medium border transition-all",
6723
+ style: {
6724
+ backgroundColor: answer?.answer_rating === value ? primaryColor : "transparent",
6725
+ borderColor: answer?.answer_rating === value ? primaryColor : isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)",
6726
+ color: answer?.answer_rating === value ? "white" : "var(--appgram-foreground)",
6727
+ borderRadius: `${Math.min(borderRadius, 8)}px`
6728
+ },
6729
+ children: value
6730
+ },
6731
+ value
6732
+ )) });
6733
+ }
6734
+ default:
6735
+ return /* @__PURE__ */ jsx("div", {});
6736
+ }
6737
+ }
6738
+ function ContactFormRenderer({
6739
+ formId,
6740
+ projectId,
6741
+ title,
6742
+ description,
6743
+ onSuccess,
6744
+ onError,
6745
+ className
6746
+ }) {
6747
+ const { theme } = useAppgramContext();
6748
+ const { form, isLoading, error: fetchError } = useContactForm(formId);
6749
+ const {
6750
+ submitForm,
6751
+ isSubmitting,
6752
+ error: submitError,
6753
+ successMessage,
6754
+ validateField,
6755
+ clearMessages
6756
+ } = useContactFormSubmit({
6757
+ onSuccess: () => onSuccess?.(),
6758
+ onError
6759
+ });
6760
+ const [formData, setFormData] = useState({});
6761
+ const [fieldErrors, setFieldErrors] = useState({});
6762
+ const primaryColor = theme.colors?.primary || "#0EA5E9";
6763
+ const borderRadius = theme.borderRadius || 16;
6764
+ const isDark = theme.isDark ?? false;
6765
+ const handleFieldChange = useCallback((fieldId, value) => {
6766
+ setFormData((prev) => ({ ...prev, [fieldId]: value }));
6767
+ setFieldErrors((prev) => {
6768
+ const next = { ...prev };
6769
+ delete next[fieldId];
6770
+ return next;
6771
+ });
6772
+ }, []);
6773
+ const handleSubmit = useCallback(async (e) => {
6774
+ e.preventDefault();
6775
+ if (!form) return;
6776
+ const errors = {};
6777
+ for (const field of form.fields) {
6778
+ const value = formData[field.id];
6779
+ if (field.type === "checkbox") continue;
6780
+ const error = validateField(String(value || ""), field);
6781
+ if (error) errors[field.id] = error;
6782
+ }
6783
+ if (Object.keys(errors).length > 0) {
6784
+ setFieldErrors(errors);
6785
+ return;
6786
+ }
6787
+ const result = await submitForm(projectId, formId, { data: formData });
6788
+ if (result) {
6789
+ setFormData({});
6790
+ setFieldErrors({});
6791
+ }
6792
+ }, [form, formData, validateField, submitForm, projectId, formId]);
6793
+ if (successMessage) {
6794
+ return /* @__PURE__ */ jsx("div", { className: cn("max-w-2xl mx-auto", className), children: /* @__PURE__ */ jsxs(
6795
+ "div",
6796
+ {
6797
+ className: "rounded-lg border p-8 text-center",
6798
+ style: {
6799
+ backgroundColor: isDark ? "var(--appgram-card)" : "rgba(255, 255, 255, 0.7)",
6800
+ borderColor: isDark ? "rgba(255, 255, 255, 0.05)" : "rgba(0, 0, 0, 0.05)",
6801
+ borderRadius: `${Math.min(borderRadius, 12)}px`
6802
+ },
6803
+ children: [
6804
+ /* @__PURE__ */ jsx(
6805
+ "div",
6806
+ {
6807
+ className: "inline-flex items-center justify-center w-16 h-16 rounded-full mb-6",
6808
+ style: { backgroundColor: "#10b98115" },
6809
+ children: /* @__PURE__ */ jsx("svg", { className: "w-8 h-8", style: { color: "#10b981" }, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) })
6810
+ }
6811
+ ),
6812
+ /* @__PURE__ */ jsx(
6813
+ "h2",
6814
+ {
6815
+ className: "text-2xl font-bold mb-3",
6816
+ style: { color: "var(--appgram-foreground)" },
6817
+ children: form?.successMessage || "Thank You"
6818
+ }
6819
+ ),
6820
+ /* @__PURE__ */ jsx(
6821
+ "p",
6822
+ {
6823
+ className: "text-base mb-6",
6824
+ style: { color: isDark ? "rgba(255, 255, 255, 0.6)" : "rgba(0, 0, 0, 0.6)" },
6825
+ children: successMessage
6826
+ }
6827
+ ),
6828
+ /* @__PURE__ */ jsx(
6829
+ "button",
6830
+ {
6831
+ onClick: clearMessages,
6832
+ className: "px-6 py-3 text-white font-medium transition-all hover:shadow-lg",
6833
+ style: {
6834
+ backgroundColor: primaryColor,
6835
+ borderRadius: `${Math.min(borderRadius, 12)}px`
6836
+ },
6837
+ children: "Submit Another"
6838
+ }
6839
+ )
6840
+ ]
6841
+ }
6842
+ ) });
6843
+ }
6844
+ if (isLoading) {
6845
+ return /* @__PURE__ */ jsx("div", { className: cn("max-w-2xl mx-auto flex items-center justify-center py-12", className), children: /* @__PURE__ */ jsx(
6846
+ "div",
6847
+ {
6848
+ className: "w-8 h-8 border-2 border-t-transparent rounded-full animate-spin",
6849
+ style: { borderColor: primaryColor, borderTopColor: "transparent" }
6850
+ }
6851
+ ) });
6852
+ }
6853
+ if (fetchError) {
6854
+ return /* @__PURE__ */ jsx("div", { className: cn("max-w-2xl mx-auto", className), children: /* @__PURE__ */ jsx(
6855
+ "div",
6856
+ {
6857
+ className: "p-4 text-sm",
6858
+ style: {
6859
+ backgroundColor: "rgba(239, 68, 68, 0.1)",
6860
+ color: "#dc2626",
6861
+ borderRadius: `${Math.min(borderRadius, 8)}px`
6862
+ },
6863
+ children: fetchError
6864
+ }
6865
+ ) });
6866
+ }
6867
+ if (!form) return /* @__PURE__ */ jsx("div", {});
6868
+ return /* @__PURE__ */ jsxs("div", { className: cn("max-w-2xl mx-auto", className), children: [
6869
+ (title || form.name) && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
6870
+ /* @__PURE__ */ jsx(
6871
+ "h1",
6872
+ {
6873
+ className: "text-2xl font-bold mb-2",
6874
+ style: { color: "var(--appgram-foreground)" },
6875
+ children: title || form.name
6876
+ }
6877
+ ),
6878
+ (description || form.description) && /* @__PURE__ */ jsx(
6879
+ "p",
6880
+ {
6881
+ className: "text-base",
6882
+ style: { color: isDark ? "rgba(255, 255, 255, 0.6)" : "rgba(0, 0, 0, 0.6)" },
6883
+ children: description || form.description
6884
+ }
6885
+ )
6886
+ ] }),
6887
+ /* @__PURE__ */ jsxs(
6888
+ "div",
6889
+ {
6890
+ className: "rounded-lg border p-6",
6891
+ style: {
6892
+ backgroundColor: isDark ? "var(--appgram-card)" : "rgba(255, 255, 255, 0.7)",
6893
+ borderColor: isDark ? "rgba(255, 255, 255, 0.05)" : "rgba(0, 0, 0, 0.05)",
6894
+ borderRadius: `${Math.min(borderRadius, 12)}px`
6895
+ },
6896
+ children: [
6897
+ submitError && /* @__PURE__ */ jsx(
6898
+ "div",
6899
+ {
6900
+ className: "p-3 text-sm mb-4",
6901
+ style: {
6902
+ backgroundColor: "rgba(239, 68, 68, 0.1)",
6903
+ color: "#dc2626",
6904
+ borderRadius: `${Math.min(borderRadius, 8)}px`
6905
+ },
6906
+ children: submitError
6907
+ }
6908
+ ),
6909
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-5", children: [
6910
+ form.fields.map((field) => /* @__PURE__ */ jsx(
6911
+ FormFieldInput,
6912
+ {
6913
+ field,
6914
+ value: formData[field.id],
6915
+ error: fieldErrors[field.id],
6916
+ onChange: (value) => handleFieldChange(field.id, value),
6917
+ primaryColor,
6918
+ borderRadius,
6919
+ isDark
6920
+ },
6921
+ field.id
6922
+ )),
6923
+ /* @__PURE__ */ jsx(
6924
+ "button",
6925
+ {
6926
+ type: "submit",
6927
+ disabled: isSubmitting,
6928
+ className: "w-full flex items-center justify-center gap-2 py-3 text-white font-medium transition-all hover:shadow-lg disabled:opacity-50",
6929
+ style: {
6930
+ backgroundColor: primaryColor,
6931
+ borderRadius: `${Math.min(borderRadius, 8)}px`
6932
+ },
6933
+ children: isSubmitting ? "Submitting..." : form.submitButtonText || "Submit"
6934
+ }
6935
+ )
6936
+ ] })
6937
+ ]
6938
+ }
6939
+ )
6940
+ ] });
6941
+ }
6942
+ function FormFieldInput({
6943
+ field,
6944
+ value,
6945
+ error,
6946
+ onChange,
6947
+ primaryColor,
6948
+ borderRadius,
6949
+ isDark
6950
+ }) {
6951
+ const inputStyles = {
6952
+ backgroundColor: isDark ? "var(--appgram-card)" : "white",
6953
+ borderColor: error ? "#dc2626" : isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)",
6954
+ color: "var(--appgram-foreground)",
6955
+ borderRadius: `${Math.min(borderRadius, 8)}px`
6956
+ };
6957
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
6958
+ field.type !== "checkbox" && /* @__PURE__ */ jsxs("label", { className: "text-sm font-medium", style: { color: "var(--appgram-foreground)" }, children: [
6959
+ field.label,
6960
+ field.required && /* @__PURE__ */ jsx("span", { style: { color: "#dc2626" }, children: " *" })
6961
+ ] }),
6962
+ field.type === "text" && /* @__PURE__ */ jsx(
6963
+ "input",
6964
+ {
6965
+ type: "text",
6966
+ value: String(value || ""),
6967
+ onChange: (e) => onChange(e.target.value),
6968
+ placeholder: field.placeholder,
6969
+ required: field.required,
6970
+ className: "w-full h-10 px-4 text-sm border focus:outline-none focus:ring-2 transition-all",
6971
+ style: inputStyles
6972
+ }
6973
+ ),
6974
+ field.type === "email" && /* @__PURE__ */ jsx(
6975
+ "input",
6976
+ {
6977
+ type: "email",
6978
+ value: String(value || ""),
6979
+ onChange: (e) => onChange(e.target.value),
6980
+ placeholder: field.placeholder || "you@example.com",
6981
+ required: field.required,
6982
+ className: "w-full h-10 px-4 text-sm border focus:outline-none focus:ring-2 transition-all",
6983
+ style: inputStyles
6984
+ }
6985
+ ),
6986
+ field.type === "textarea" && /* @__PURE__ */ jsx(
6987
+ "textarea",
6988
+ {
6989
+ value: String(value || ""),
6990
+ onChange: (e) => onChange(e.target.value),
6991
+ placeholder: field.placeholder,
6992
+ required: field.required,
6993
+ rows: 4,
6994
+ className: "w-full px-4 py-3 text-sm border focus:outline-none focus:ring-2 resize-none transition-all",
6995
+ style: inputStyles
6996
+ }
6997
+ ),
6998
+ field.type === "select" && /* @__PURE__ */ jsxs(
6999
+ "select",
7000
+ {
7001
+ value: String(value || ""),
7002
+ onChange: (e) => onChange(e.target.value),
7003
+ required: field.required,
7004
+ className: "w-full h-10 px-4 text-sm border focus:outline-none focus:ring-2 transition-all appearance-none",
7005
+ style: inputStyles,
7006
+ children: [
7007
+ /* @__PURE__ */ jsx("option", { value: "", children: field.placeholder || "Select an option" }),
7008
+ (field.options || []).map((opt) => /* @__PURE__ */ jsx("option", { value: opt, children: opt }, opt))
7009
+ ]
7010
+ }
7011
+ ),
7012
+ field.type === "radio" && /* @__PURE__ */ jsx("div", { className: "space-y-2", children: (field.options || []).map((opt) => /* @__PURE__ */ jsxs(
7013
+ "label",
7014
+ {
7015
+ className: "flex items-center gap-3 px-4 py-3 text-sm border cursor-pointer transition-all",
7016
+ style: {
7017
+ backgroundColor: value === opt ? `${primaryColor}15` : "transparent",
7018
+ borderColor: value === opt ? primaryColor : isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)",
7019
+ color: "var(--appgram-foreground)",
7020
+ borderRadius: `${Math.min(borderRadius, 8)}px`
7021
+ },
7022
+ children: [
7023
+ /* @__PURE__ */ jsx(
7024
+ "input",
7025
+ {
7026
+ type: "radio",
7027
+ name: field.id,
7028
+ value: opt,
7029
+ checked: value === opt,
7030
+ onChange: () => onChange(opt),
7031
+ className: "sr-only"
7032
+ }
7033
+ ),
7034
+ /* @__PURE__ */ jsx(
7035
+ "div",
7036
+ {
7037
+ className: "w-4 h-4 rounded-full border-2 flex items-center justify-center shrink-0",
7038
+ style: {
7039
+ borderColor: value === opt ? primaryColor : isDark ? "rgba(255, 255, 255, 0.3)" : "rgba(0, 0, 0, 0.3)"
7040
+ },
7041
+ children: value === opt && /* @__PURE__ */ jsx(
7042
+ "div",
7043
+ {
7044
+ className: "w-2 h-2 rounded-full",
7045
+ style: { backgroundColor: primaryColor }
7046
+ }
7047
+ )
7048
+ }
7049
+ ),
7050
+ opt
7051
+ ]
7052
+ },
7053
+ opt
7054
+ )) }),
7055
+ field.type === "checkbox" && /* @__PURE__ */ jsxs(
7056
+ "label",
7057
+ {
7058
+ className: "flex items-center gap-3 cursor-pointer",
7059
+ style: { color: "var(--appgram-foreground)" },
7060
+ children: [
7061
+ /* @__PURE__ */ jsx(
7062
+ "div",
7063
+ {
7064
+ className: "w-4 h-4 border rounded flex items-center justify-center shrink-0 cursor-pointer",
7065
+ style: {
7066
+ borderColor: value ? primaryColor : isDark ? "rgba(255, 255, 255, 0.3)" : "rgba(0, 0, 0, 0.3)",
7067
+ backgroundColor: value ? primaryColor : "transparent"
7068
+ },
7069
+ onClick: () => onChange(!value),
7070
+ children: value && /* @__PURE__ */ jsx("svg", { className: "w-3 h-3 text-white", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 3, d: "M5 13l4 4L19 7" }) })
7071
+ }
7072
+ ),
7073
+ /* @__PURE__ */ jsxs("span", { className: "text-sm", onClick: () => onChange(!value), children: [
7074
+ field.label,
7075
+ field.required && /* @__PURE__ */ jsx("span", { style: { color: "#dc2626" }, children: " *" })
7076
+ ] })
7077
+ ]
7078
+ }
7079
+ ),
7080
+ error && /* @__PURE__ */ jsx("p", { className: "text-xs", style: { color: "#dc2626" }, children: error })
7081
+ ] });
7082
+ }
6338
7083
 
6339
- export { HelpArticleDetail, HelpArticles, HelpCenter, HelpCollections, ReleaseCard, ReleaseDetail, ReleaseList, Releases, RoadmapBoard, RoadmapColumn, StatusBoard, StatusIncidentDetail, SubmitWishForm, SupportForm, VoteButton, WhatsNewPopup, WishCard, WishDetail, WishList };
6340
- //# sourceMappingURL=chunk-AIDLOCVJ.mjs.map
6341
- //# sourceMappingURL=chunk-AIDLOCVJ.mjs.map
7084
+ export { ContactFormRenderer, HelpArticleDetail, HelpArticles, HelpCenter, HelpCollections, ReleaseCard, ReleaseDetail, ReleaseList, Releases, RoadmapBoard, RoadmapColumn, StatusBoard, StatusIncidentDetail, SubmitWishForm, SupportForm, SurveyRenderer, VoteButton, WhatsNewPopup, WishCard, WishDetail, WishList };
7085
+ //# sourceMappingURL=chunk-UWIJR4ZY.mjs.map
7086
+ //# sourceMappingURL=chunk-UWIJR4ZY.mjs.map