interview-widget 0.0.7 → 0.0.9

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 (33) hide show
  1. package/README.md +197 -101
  2. package/dist/components/interview/interview-controller.d.ts +8 -0
  3. package/dist/components/interview/interview-header.d.ts +1 -0
  4. package/dist/components/interview/question-display.d.ts +3 -2
  5. package/dist/components/modals/exit-confirmation-modal.d.ts +7 -0
  6. package/dist/components/timer/timer-display.d.ts +13 -0
  7. package/dist/components/ui/dialog.d.ts +13 -0
  8. package/dist/context/interview-widget-context.d.ts +34 -0
  9. package/dist/hooks/use-api.d.ts +26 -0
  10. package/dist/hooks/use-dialog.d.ts +6 -0
  11. package/dist/hooks/use-interview-api.d.ts +5 -0
  12. package/dist/hooks/use-stt.d.ts +20 -0
  13. package/dist/hooks/use-timer.d.ts +12 -0
  14. package/dist/hooks/use-tts.d.ts +15 -0
  15. package/dist/index.d.ts +3 -2
  16. package/dist/services/api/index.d.ts +2 -0
  17. package/dist/services/api/interview-api.d.ts +23 -0
  18. package/dist/services/stt/index.d.ts +1 -0
  19. package/dist/services/stt/stt-service.d.ts +78 -0
  20. package/dist/services/timer/index.d.ts +6 -0
  21. package/dist/services/timer/timer-service.d.ts +81 -0
  22. package/dist/services/tts/index.d.ts +1 -0
  23. package/dist/services/tts/tts-service.d.ts +43 -0
  24. package/dist/types.d.ts +69 -14
  25. package/dist/utils/api-error-classifier.d.ts +2 -0
  26. package/dist/utils/constants.d.ts +3 -0
  27. package/dist/utils/helper.d.ts +6 -0
  28. package/dist/utils/resilient-fetch.d.ts +9 -0
  29. package/dist/widget.css +1 -1
  30. package/dist/widget.es.js +1714 -250
  31. package/dist/widget.umd.js +2 -2
  32. package/package.json +1 -1
  33. /package/dist/components/{onboarding-modal.d.ts → modals/onboarding-modal.d.ts} +0 -0
@@ -1,4 +1,4 @@
1
- (function(x,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],n):(x=typeof globalThis<"u"?globalThis:x||self,n(x.InterviewWidget={},x.React))})(this,function(x,n){"use strict";var C={exports:{}},b={};/**
1
+ (function(N,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("react"),require("react-dom")):typeof define=="function"&&define.amd?define(["exports","react","react-dom"],c):(N=typeof globalThis<"u"?globalThis:N||self,c(N.InterviewWidget={},N.React,N.ReactDOM))})(this,function(N,c,P){"use strict";var Be=Object.defineProperty;var He=(N,c,P)=>c in N?Be(N,c,{enumerable:!0,configurable:!0,writable:!0,value:P}):N[c]=P;var v=(N,c,P)=>He(N,typeof c!="symbol"?c+"":c,P);var W={exports:{}},_={};/**
2
2
  * @license React
3
3
  * react-jsx-runtime.production.js
4
4
  *
@@ -6,4 +6,4 @@
6
6
  *
7
7
  * This source code is licensed under the MIT license found in the
8
8
  * LICENSE file in the root directory of this source tree.
9
- */var I=Symbol.for("react.transitional.element"),$=Symbol.for("react.fragment");function E(r,s,i){var a=null;if(i!==void 0&&(a=""+i),s.key!==void 0&&(a=""+s.key),"key"in s){i={};for(var t in s)t!=="key"&&(i[t]=s[t])}else i=s;return s=i.ref,{$$typeof:I,type:r,key:a,ref:s!==void 0?s:null,props:i}}b.Fragment=$,b.jsx=E,b.jsxs=E,C.exports=b;var e=C.exports;const N=({children:r,variant:s="primary",size:i="md",fullWidth:a=!1,isLoading:t=!1,disabled:o,className:l="",...c})=>{const u="iw-inline-flex iw-items-center iw-justify-center iw-rounded-md iw-font-medium iw-transition-colors iw-focus:outline-none iw-focus:ring-2 iw-focus:ring-primary-500 iw-focus:ring-offset-2",m={primary:"iw-bg-primary-600 iw-text-white iw-hover:bg-primary-700 iw-border iw-border-transparent",secondary:"iw-bg-primary-100 iw-text-primary-700 iw-hover:bg-primary-200 iw-border iw-border-transparent",outline:"iw-bg-transparent iw-text-primary-700 iw-border iw-border-primary-500 iw-hover:bg-primary-50",text:"iw-bg-transparent iw-text-primary-600 iw-hover:bg-primary-50 iw-border iw-border-transparent",gradient:"iw-text-white iw-border iw-border-transparent iw-bg-gradient-to-r iw-from-purple-500 iw-to-indigo-500 hover:iw-from-purple-600 hover:iw-to-indigo-600"},d={sm:"iw-px-3 iw-py-1.5 iw-text-sm",md:"iw-px-4 iw-py-2 iw-text-sm",lg:"iw-px-5 iw-py-2.5 iw-text-base"},f="iw-disabled:opacity-50 iw-disabled:cursor-not-allowed iw-disabled:pointer-events-none",h=a?"iw-w-full":"";return e.jsxs("button",{className:`${u} ${m[s]} ${d[i]} ${h} ${f} ${l}`,disabled:o||t,...c,children:[t&&e.jsxs("svg",{className:"iw-animate-spin iw-mr-2 iw-h-4 iw-w-4 iw-text-white",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",children:[e.jsx("circle",{className:"iw-opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),e.jsx("path",{className:"iw-opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),r]})},M=({isOpen:r,onStart:s,onClose:i})=>{var j;const a=n.useRef(null),t=n.useRef(null),[o,l]=n.useState(!1),[c,u]=n.useState(null),[m,d]=n.useState(!1),f=()=>{t.current&&(t.current.getTracks().forEach(w=>w.stop()),t.current=null)},h=async()=>{d(!0),u(null);try{const w=await navigator.mediaDevices.getUserMedia({video:{width:{ideal:1280},height:{ideal:720}},audio:!0});t.current=w,a.current&&(a.current.srcObject=w),l(!0)}catch(w){console.error("Media permission error:",w);let p="Unable to access camera or microphone.";(w==null?void 0:w.name)==="NotAllowedError"?p="Permissions denied. Please allow access to camera and microphone.":(w==null?void 0:w.name)==="NotFoundError"?p="No camera/microphone found. Please connect a device and retry.":w!=null&&w.message&&(p=w.message),l(!1),u(p)}finally{d(!1)}};if(n.useEffect(()=>{if(!r){f();return}return h(),()=>{f()}},[r]),!r)return null;const k=()=>{s(),f()};return e.jsx("div",{className:"iw-fixed iw-inset-0 iw-z-50 iw-flex iw-items-center iw-justify-center iw-bg-black/50 iw-backdrop-blur-sm",children:e.jsxs("div",{className:"iw-bg-white iw-rounded-xl iw-shadow-2xl iw-w-full iw-max-w-3xl iw-mx-4",children:[e.jsxs("div",{className:"iw-px-5 iw-py-4 iw-border-b iw-border-gray-200 iw-flex iw-items-center iw-justify-between",children:[e.jsx("h2",{className:"iw-text-base iw-font-semibold",children:"Camera & Microphone Check"}),i&&e.jsx("button",{"aria-label":"Close",className:"iw-text-gray-500 hover:iw-text-gray-700",onClick:()=>{f(),i==null||i()},children:"✕"})]}),e.jsxs("div",{className:"iw-p-4 iw-grid iw-grid-cols-2 iw-gap-4",children:[e.jsx("div",{className:"iw-border iw-border-gray-200 iw-rounded-lg iw-overflow-hidden iw-bg-gray-900",children:e.jsx("video",{ref:a,autoPlay:!0,playsInline:!0,muted:!0,className:"iw-w-full iw-h-64 iw-object-cover"})}),e.jsxs("div",{className:"iw-flex iw-flex-col iw-gap-3",children:[e.jsx("p",{className:"iw-text-sm iw-text-gray-700",children:"We will need access to your camera and microphone. Grant permission to preview your setup and to enable the Start Interview button."}),!((j=navigator.mediaDevices)!=null&&j.getUserMedia)&&e.jsx("div",{className:"iw-text-xs iw-text-red-600",children:"Your browser does not support media devices. Please use a modern browser like Chrome, Edge, or Firefox."}),c&&e.jsx("div",{className:"iw-text-xs iw-text-red-600",children:c}),e.jsxs("div",{className:"iw-flex iw-items-center iw-gap-2",children:[e.jsx(N,{onClick:h,isLoading:m,variant:"outline",size:"sm",children:o?"Recheck Permissions":"Enable Camera & Mic"}),e.jsx(N,{onClick:k,disabled:!o,size:"sm",children:"Start Interview"})]}),e.jsxs("ul",{className:"iw-text-xs iw-text-gray-500 iw-pt-2 iw-list-disc iw-pl-4",children:[e.jsx("li",{children:"Your preview is muted to avoid echo."}),e.jsx("li",{children:"You can change devices from your browser’s site settings."})]})]})]})]})})},P=({title:r})=>e.jsxs("header",{className:"iw-w-full iw-text-gray-900",children:[e.jsxs("div",{className:"iw-mx-auto iw-flex iw-items-center iw-justify-between iw-px-4 iw-py-3",children:[e.jsxs("div",{className:"iw-flex iw-items-center iw-space-x-2",children:[e.jsx("div",{className:"iw-h-7 iw-w-7 iw-rounded-md iw-bg-purple-500 iw-flex iw-items-center iw-justify-center iw-text-white iw-font-semibold",children:"N"}),e.jsx("p",{className:"iw-text-sm iw-font-medium",children:"Novara"})]}),e.jsx("h1",{className:"iw-text-base iw-font-medium",children:r}),e.jsx("button",{className:"iw-text-sm iw-text-gray-500 hover:iw-text-gray-700",children:"Exit Interview"})]}),e.jsx("div",{className:"iw-h-px iw-bg-gray-200"})]}),R=({question:r})=>e.jsxs("div",{className:"iw-rounded-xl iw-mb-4 message-animation iw-bg-gradient-to-b iw-from-indigo-50 iw-to-white iw-text-gray-800 iw-border iw-border-indigo-100 iw-p-5",style:{background:"linear-gradient(to bottom, #eef2ff, #ffffff)",border:"1px solid #e0e7ff",color:"#1f2937"},children:[e.jsxs("div",{className:"iw-flex iw-items-center iw-space-x-3 iw-mb-3",children:[e.jsx("div",{className:"iw-h-12 iw-w-12 iw-rounded-lg iw-bg-purple-500 iw-flex iw-items-center iw-justify-center iw-text-white iw-font-semibold",children:"N"}),e.jsxs("div",{children:[e.jsx("div",{className:"iw-text-sm iw-font-semibold",children:"Novara"}),e.jsx("div",{className:"iw-text-xs iw-text-gray-500",children:"Assistant"})]})]}),e.jsx("p",{className:"iw-text-[15px] iw-leading-6",children:r.text}),r.type==="multiple-choice"&&r.options&&e.jsx("div",{className:"iw-mt-3 iw-space-y-2",children:r.options.map((s,i)=>e.jsx("div",{className:"iw-p-2 iw-rounded iw-border iw-border-gray-300 iw-hover:bg-gray-100 iw-cursor-pointer iw-transition-colors",children:s},i))})]}),T=({className:r=""})=>{const s=n.useRef(null);return n.useEffect(()=>{let i=null;return(async()=>{try{i=await navigator.mediaDevices.getUserMedia({video:!0,audio:!1}),s.current&&(s.current.srcObject=i)}catch(t){console.error("Error accessing camera:",t)}})(),()=>{i&&i.getTracks().forEach(t=>t.stop())}},[]),e.jsx("div",{className:`iw-relative ${r}`,children:e.jsx("video",{ref:s,autoPlay:!0,playsInline:!0,muted:!0,className:"iw-w-full iw-h-full iw-object-cover iw-rounded-md"})})},A=({label:r,error:s,fullWidth:i=!1,className:a="",id:t,...o})=>{const l=t||`textarea-${Math.random().toString(36).substring(2,9)}`,c="iw-block iw-rounded-md iw-border iw-border-gray-300 iw-shadow-sm iw-px-4 iw-py-2 iw-text-sm iw-focus:border-primary-500 iw-focus:ring-primary-500 iw-focus:outline-none iw-transition-all",u=s?"iw-border-red-500 iw-focus:border-red-500 iw-focus:ring-red-500":"",m=i?"iw-w-full":"",d=a.includes("iw-h-full")?"iw-h-full":"";return e.jsxs("div",{className:`${i?"iw-w-full iw-h-full":""} ${d?"iw-flex iw-flex-col":""}`,children:[r&&e.jsx("label",{htmlFor:l,className:"iw-block iw-text-sm iw-font-medium iw-text-gray-700 iw-mb-1",children:r}),e.jsx("textarea",{id:l,className:`${c} ${u} ${m} ${d} ${a}`,"aria-invalid":s?"true":"false",...o}),s&&e.jsx("p",{className:"iw-mt-1 iw-text-sm iw-text-red-600",children:s})]})},D=({value:r,onChange:s,onSubmit:i,isSubmitDisabled:a,remainingTimeText:t})=>{const o=l=>{l.key==="Enter"&&(l.ctrlKey||l.metaKey)&&!a&&(l.preventDefault(),i())};return e.jsx("div",{className:"iw-mt-auto",children:e.jsxs("div",{className:"iw-rounded-xl iw-overflow-hidden iw-border iw-border-gray-200",children:[e.jsxs("div",{className:"iw-flex iw-items-center iw-justify-between iw-px-3 iw-py-2 iw-bg-gray-50 iw-border-b iw-border-gray-200",children:[e.jsx("div",{className:"iw-text-sm iw-font-medium",children:"Your answer"}),t&&e.jsx("div",{className:"iw-text-xs iw-text-gray-500",children:t})]}),e.jsx(A,{value:r,onChange:s,onKeyDown:o,placeholder:"Type your answer here...",className:"iw-bg-gray-50 iw-w-full iw-resize-none iw-focus:outline-none iw-bg-transparent iw-min-h-[112px]",rows:5,fullWidth:!0}),e.jsxs("div",{className:"iw-p-2 iw-flex iw-justify-between iw-items-center iw-bg-gray-50",children:[e.jsx("div",{className:"iw-text-xs iw-text-gray-500",children:e.jsx("kbd",{children:" Press Ctrl+Enter to submit"})}),e.jsx(N,{onClick:i,disabled:a,size:"sm",variant:"gradient",children:"Submit Answer"})]})]})})},S=({title:r="Interview",questions:s=[],onComplete:i,onAnswerSubmit:a,className:t=""})=>{const[o,l]=n.useState(0),[c,u]=n.useState([]),[m,d]=n.useState(""),[f,h]=n.useState(!1),[k,j]=n.useState(!0),[w,p]=n.useState(!1),[z]=n.useState(!0),_=n.useRef(null),v=s[o],F=()=>{const g={questionId:(v==null?void 0:v.id)||"",answerText:m,timestamp:new Date};u([...c,g]),a&&a(g),o<s.length-1?(l(y=>y+1),d("")):(h(!0),i&&i(c))},G=n.useMemo(()=>{const y=60-Math.floor(Date.now()/1e3%60),Q=Math.floor(y/60).toString().padStart(2,"0"),W=(y%60).toString().padStart(2,"0");return`Time to Talk: ${Q}:${W} min`},[o]);return w?e.jsx("div",{className:"interview-widget-container",children:e.jsx("div",{ref:_,className:`iw-flex iw-flex-col iw-rounded-xl iw-shadow-lg iw-overflow-hidden iw-h-[calc(100vh-1rem)] ${t}`,children:e.jsxs("div",{className:" iw-h-full iw-flex iw-flex-col",children:[e.jsx(P,{title:r}),e.jsx("div",{className:"iw-flex iw-flex-col iw-flex-grow iw-overflow-hidden iw-px-4 iw-py-5",children:f?e.jsxs("div",{className:"iw-flex iw-flex-col iw-items-center iw-justify-center iw-h-full",children:[e.jsx("div",{className:"iw-text-xl iw-font-bold iw-mb-2",children:"Interview Complete!"}),e.jsx("p",{className:"iw-text-center iw-mb-4",children:"Thank you for participating in this interview."})]}):e.jsxs("div",{className:"iw-h-full iw-flex iw-flex-col ",children:[e.jsx("div",{className:"iw-flex-1",children:v&&e.jsx(R,{question:v})}),e.jsxs("div",{className:"iw-grid iw-grid-cols-2 iw-gap-4 iw-mt-4",children:[z&&e.jsx("div",{className:"iw-mt-2 iw-border iw-border-gray-200 iw-rounded-xl iw-p-2",children:e.jsx(T,{className:"iw-w-full iw-h-[400px]"})}),e.jsx(D,{value:m,onChange:g=>d(g.target.value),onSubmit:F,isSubmitDisabled:!m.trim()||!w,remainingTimeText:G})]})]})})]})})}):e.jsx("div",{className:"interview-widget-container iw-h-screen iw-w-screen",children:e.jsx(M,{isOpen:k,onStart:()=>{console.log("Permissions granted, starting interview"),p(!0),j(!1)}})})};typeof window<"u"&&(window.InterviewWidget={InterviewWidget:S}),x.InterviewWidget=S,x.default=S,Object.defineProperties(x,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
9
+ */var te=Symbol.for("react.transitional.element"),re=Symbol.for("react.fragment");function z(t,r,e){var a=null;if(e!==void 0&&(a=""+e),r.key!==void 0&&(a=""+r.key),"key"in r){e={};for(var s in r)s!=="key"&&(e[s]=r[s])}else e=r;return r=e.ref,{$$typeof:te,type:t,key:a,ref:r!==void 0?r:null,props:e}}_.Fragment=re,_.jsx=z,_.jsxs=z,W.exports=_;var i=W.exports;const j={api:{baseUrl:"/api",retryConfig:{attempts:3,backoff:"exponential",baseDelay:1e3}},ui:{baseColor:"#3B82F6",borderRadius:"8px"},interview:{timers:{thinkingDuration:30,answeringDuration:120,editingDuration:30},stt:{provider:"groq",model:"whisper-large-v3-turbo",language:"en"},tts:{provider:"piper"}}},Y=c.createContext(null);function K({config:t={},children:r}){var a,s,l,n;const e={api:{...j.api,...t.api,retryConfig:{...j.api.retryConfig,...(a=t.api)==null?void 0:a.retryConfig}},ui:{...j.ui,...t.ui},interview:{...j.interview,...t.interview,timers:{...j.interview.timers,...(s=t.interview)==null?void 0:s.timers},stt:{...j.interview.stt,...(l=t.interview)==null?void 0:l.stt},tts:{...j.interview.tts,...(n=t.interview)==null?void 0:n.tts}}};return i.jsx(Y.Provider,{value:e,children:r})}function $(){const t=c.useContext(Y);if(!t)throw new Error("useInterviewConfig must be used within an InterviewWidgetProvider. Wrap your component tree with <InterviewWidgetProvider config={...}>");return t}function se(){return $().api||j.api}function L(){return $().ui||j.ui}function ne(){return $().interview||j.interview}const ae=({isOpen:t,onClose:r,children:e,title:a,showCloseButton:s=!0,closeOnOverlayClick:l=!0,closeOnEscape:n=!0,className:o=""})=>{if(c.useEffect(()=>{if(!t||!n)return;const u=m=>{m.key==="Escape"&&r()};return document.addEventListener("keydown",u),()=>document.removeEventListener("keydown",u)},[t,n,r]),c.useEffect(()=>(t?(document.body.style.overflow="hidden",document.body.classList.add("interview-widget-container")):(document.body.style.overflow="unset",document.body.classList.remove("interview-widget-container")),()=>{document.body.style.overflow="unset"}),[t]),!t)return null;const g=u=>{l&&u.target===u.currentTarget&&r()},h=i.jsxs("div",{className:"iw-fixed iw-inset-0 iw-z-50 iw-flex iw-items-center iw-justify-center",children:[i.jsx("div",{className:"iw-fixed iw-inset-0 iw-bg-black iw-bg-opacity-50 iw-transition-opacity",onClick:g}),i.jsxs("div",{className:`iw-relative iw-bg-white iw-rounded-lg iw-shadow-xl iw-max-w-md iw-w-full iw-mx-4 iw-max-h-[90vh] iw-overflow-hidden ${o}`,role:"dialog","aria-modal":"true","aria-labelledby":a?"dialog-title":void 0,children:[(a||s)&&i.jsxs("div",{className:"iw-flex iw-items-center iw-justify-between iw-p-4 iw-border-b iw-border-gray-200",children:[a&&i.jsx("h2",{id:"dialog-title",className:"iw-text-lg iw-font-semibold iw-text-gray-900",children:a}),s&&i.jsx("button",{onClick:r,className:"iw-p-1 iw-text-gray-400 iw-hover:text-gray-600 iw-transition-colors iw-rounded iw-hover:bg-gray-100","aria-label":"Close dialog",children:i.jsx("svg",{className:"iw-w-5 iw-h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:i.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),i.jsx("div",{className:"iw-p-4 iw-overflow-y-auto",children:e})]})]});return P.createPortal(h,document.body)},oe=({confirmExitInterview:t,isOpen:r,onClose:e})=>i.jsx(ae,{isOpen:r,onClose:e,title:"Exit Interview",children:i.jsxs("div",{className:"iw-space-y-4",children:[i.jsx("p",{className:"iw-text-base iw-text-gray-700",children:"Are you sure you want to exit the interview? All progress will be lost and you will not be able to resume."}),i.jsxs("div",{className:"iw-flex iw-justify-end iw-space-x-2",children:[i.jsx("button",{className:"iw-px-4 iw-py-2 iw-bg-gray-200 iw-rounded iw-text-gray-700 iw-font-medium",onClick:e,children:"Cancel"}),i.jsx("button",{className:"iw-px-4 iw-py-2 iw-bg-red-600 iw-text-white iw-rounded iw-font-medium",onClick:t,children:"Confirm Exit"})]})]})}),le=({title:t,onExit:r})=>{const{baseColor:e}=L(),[a,s]=c.useState(!1);return i.jsxs("header",{className:"iw-w-full iw-text-gray-900",children:[i.jsxs("div",{className:"iw-mx-auto iw-flex iw-items-center iw-justify-between iw-px-4 iw-py-3",children:[i.jsxs("div",{className:"iw-flex iw-items-center iw-space-x-2",children:[i.jsx("div",{className:"iw-h-7 iw-w-7 iw-rounded-md iw-flex iw-items-center iw-justify-center iw-text-white iw-font-semibold",style:{backgroundColor:e},children:"N"}),i.jsx("p",{className:"iw-text-sm iw-font-medium",children:"Novara"})]}),i.jsx("h1",{className:"iw-text-base iw-font-medium",children:t}),i.jsx("button",{className:"iw-text-sm iw-text-gray-500 hover:iw-text-gray-700",onClick:()=>s(!0),children:"Exit Interview"})]}),i.jsx("div",{className:"iw-h-px iw-bg-gray-200"}),i.jsx(oe,{isOpen:a,confirmExitInterview:()=>{r(),s(!1)},onClose:()=>s(!1)})]})},A=({children:t,variant:r="primary",size:e="md",fullWidth:a=!1,isLoading:s=!1,disabled:l,className:n="",...o})=>{const g="iw-inline-flex iw-items-center iw-justify-center iw-rounded-md iw-font-medium iw-transition-colors iw-focus:outline-none iw-focus:ring-2 iw-focus:ring-primary-500 iw-focus:ring-offset-2",h={primary:"iw-bg-primary-600 iw-text-white iw-hover:bg-primary-700 iw-border iw-border-transparent",secondary:"iw-bg-primary-100 iw-text-primary-700 iw-hover:bg-primary-200 iw-border iw-border-transparent",outline:"iw-bg-transparent iw-text-primary-700 iw-border iw-border-primary-500 iw-hover:bg-primary-50",text:"iw-bg-transparent iw-text-primary-600 iw-hover:bg-primary-50 iw-border iw-border-transparent",gradient:"iw-text-white iw-border iw-border-transparent iw-bg-gradient-to-r iw-from-purple-500 iw-to-indigo-500 hover:iw-from-purple-600 hover:iw-to-indigo-600"},u={sm:"iw-px-3 iw-py-1.5 iw-text-sm",md:"iw-px-4 iw-py-2 iw-text-sm",lg:"iw-px-5 iw-py-2.5 iw-text-base"},m="iw-disabled:opacity-50 iw-disabled:cursor-not-allowed iw-disabled:pointer-events-none",f=a?"iw-w-full":"";return i.jsxs("button",{className:`${g} ${h[r]} ${u[e]} ${f} ${m} ${n}`,disabled:l||s,...o,children:[s&&i.jsxs("svg",{className:"iw-animate-spin iw-mr-2 iw-h-4 iw-w-4 iw-text-white",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",children:[i.jsx("circle",{className:"iw-opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),i.jsx("path",{className:"iw-opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),t]})},ce=({isOpen:t,onStart:r,onClose:e})=>{var T;const a=c.useRef(null),s=c.useRef(null),{baseColor:l,borderRadius:n}=L(),[o,g]=c.useState(!1),[h,u]=c.useState(null),[m,f]=c.useState(!1),p=()=>{s.current&&(s.current.getTracks().forEach(w=>w.stop()),s.current=null)},k=async()=>{f(!0),u(null);try{const w=await navigator.mediaDevices.getUserMedia({video:{width:{ideal:1280},height:{ideal:720}},audio:!0});s.current=w,a.current&&(a.current.srcObject=w),g(!0)}catch(w){console.error("Media permission error:",w);let y="Unable to access camera or microphone.";(w==null?void 0:w.name)==="NotAllowedError"?y="Permissions denied. Please allow access to camera and microphone.":(w==null?void 0:w.name)==="NotFoundError"?y="No camera/microphone found. Please connect a device and retry.":w!=null&&w.message&&(y=w.message),g(!1),u(y)}finally{f(!1)}};if(c.useEffect(()=>{if(!t){p();return}return k(),()=>{p()}},[t]),!t)return null;const S=()=>{r(),p()};return i.jsx("div",{className:"iw-fixed iw-inset-0 iw-z-50 iw-flex iw-items-center iw-justify-center iw-bg-black/50 iw-backdrop-blur-sm",children:i.jsxs("div",{className:"iw-bg-white iw-rounded-xl iw-shadow-2xl iw-w-full iw-max-w-3xl iw-mx-4",children:[i.jsxs("div",{className:"iw-px-5 iw-py-4 iw-border-b iw-border-gray-200 iw-flex iw-items-center iw-justify-between",children:[i.jsx("h2",{className:"iw-text-base iw-font-semibold",children:"Camera & Microphone Check"}),e&&i.jsx("button",{"aria-label":"Close",className:"iw-text-gray-500 hover:iw-text-gray-700",onClick:()=>{p(),e==null||e()},children:"✕"})]}),i.jsxs("div",{className:"iw-p-4 iw-grid iw-grid-cols-2 iw-gap-4",children:[i.jsx("div",{className:"iw-border iw-border-gray-200 iw-rounded-lg iw-overflow-hidden iw-bg-gray-900",children:i.jsx("video",{ref:a,autoPlay:!0,playsInline:!0,muted:!0,className:"iw-w-full iw-h-64 iw-object-cover"})}),i.jsxs("div",{className:"iw-flex iw-flex-col iw-gap-3",children:[i.jsx("p",{className:"iw-text-sm iw-text-gray-700",children:"We will need access to your camera and microphone. Grant permission to preview your setup and to enable the Start Interview button."}),!((T=navigator.mediaDevices)!=null&&T.getUserMedia)&&i.jsx("div",{className:"iw-text-xs iw-text-red-600",children:"Your browser does not support media devices. Please use a modern browser like Chrome, Edge, or Firefox."}),h&&i.jsx("div",{className:"iw-text-xs iw-text-red-600",children:h}),i.jsxs("div",{className:"iw-flex iw-items-center iw-gap-2",children:[i.jsx(A,{onClick:k,isLoading:m,variant:"outline",size:"sm",style:{borderColor:l,borderRadius:n,color:l},children:o?"Recheck Permissions":"Enable Camera & Mic"}),i.jsx(A,{onClick:S,disabled:!o,size:"sm",style:{backgroundColor:l,borderRadius:n},children:"Proceed"})]}),i.jsxs("ul",{className:"iw-text-xs iw-text-gray-500 iw-pt-2 iw-list-disc iw-pl-4",children:[i.jsx("li",{children:"Your preview is muted to avoid echo."}),i.jsx("li",{children:"You can change devices from your browser’s site settings."})]})]})]})]})})};var d=(t=>(t.IDLE="idle",t.FETCHING_QUESTION="fetching_question",t.READING_QUESTION="reading_question",t.THINKING="thinking",t.ANSWERING="answering",t.TRANSCRIBING="transcribing",t.EDITING="editing",t.SUBMITTING="submitting",t.COMPLETED="completed",t))(d||{});const de={thinkingDuration:30,answeringDuration:120,editingDuration:30,totalInterviewDuration:600,minimumTimeForNextQuestion:120},ue={idle:{next:"fetching_question"},fetching_question:{next:"reading_question"},reading_question:{next:"thinking"},thinking:{next:"answering",duration:30},answering:{next:"transcribing",duration:120},transcribing:{next:"editing"},editing:{next:"submitting",duration:30},submitting:{next:"completed"},completed:{next:"completed"}};class we{constructor(r={},e={}){v(this,"config");v(this,"state");v(this,"phaseIntervalId",null);v(this,"globalIntervalId",null);v(this,"callbacks");this.config={...de,...r},this.callbacks=e,this.state={phase:"idle",currentPhaseTimeRemaining:0,totalTimeRemaining:this.config.totalInterviewDuration,totalTimeElapsed:0,currentQuestionNumber:0}}getState(){return{...this.state}}startQuestion(){var r,e;if(this.state.totalTimeRemaining<this.config.minimumTimeForNextQuestion){this.state.phase="completed",this.stopGlobalTimer(),this.stopPhaseTimer(),(e=(r=this.callbacks).onInterviewEnd)==null||e.call(r),this.notifyChange();return}this.state.currentQuestionNumber===0&&this.startGlobalTimer(),this.state.currentQuestionNumber=this.state.currentQuestionNumber+1,this.state.phase="fetching_question",this.notifyChange()}nextPhase(){const r=this.state.phase,e=ue[r];if(!e)return;this.stopPhaseTimer(),this.state.phase=e.next;const a=this.getDurationForPhase(e.next);a>0?(this.state.currentPhaseTimeRemaining=a,this.startPhaseTimer()):this.state.currentPhaseTimeRemaining=0,this.notifyChange()}destroy(){this.stopPhaseTimer(),this.stopGlobalTimer()}getDurationForPhase(r){switch(r){case"thinking":return this.config.thinkingDuration;case"answering":return this.config.answeringDuration;case"editing":return this.config.editingDuration;default:return 0}}startGlobalTimer(){this.globalIntervalId=setInterval(()=>{var r,e,a,s;this.state.totalTimeRemaining--,this.state.totalTimeElapsed++,(e=(r=this.callbacks).onTick)==null||e.call(r,this.getState()),this.state.totalTimeRemaining<=0&&(this.stopGlobalTimer(),this.stopPhaseTimer(),this.state.phase="completed",(s=(a=this.callbacks).onInterviewEnd)==null||s.call(a),this.notifyChange())},1e3)}stopGlobalTimer(){this.globalIntervalId&&(clearInterval(this.globalIntervalId),this.globalIntervalId=null)}startPhaseTimer(){this.phaseIntervalId=setInterval(()=>{this.state.currentPhaseTimeRemaining--,this.state.currentPhaseTimeRemaining<=0&&this.nextPhase()},1e3)}stopPhaseTimer(){this.phaseIntervalId&&(clearInterval(this.phaseIntervalId),this.phaseIntervalId=null)}notifyChange(){var r,e;(e=(r=this.callbacks).onPhaseChange)==null||e.call(r,this.state.phase,this.getState())}}function me(t={}){const{config:r={},callbacks:e={}}=t,a=c.useRef(null);a.current||(a.current=new we(r,{}));const s=a.current,[l,n]=c.useState(s.getState()),o=c.useCallback(()=>{n(s.getState())},[s]);c.useEffect(()=>{const u={onPhaseChange:(m,f)=>{var p;o(),(p=e.onPhaseChange)==null||p.call(e,m,f)},onTick:m=>{var f;o(),(f=e.onTick)==null||f.call(e,m)},onInterviewEnd:()=>{var m;o(),(m=e.onInterviewEnd)==null||m.call(e)}};s.callbacks=u},[s,e,o]),c.useEffect(()=>()=>{s.destroy()},[s]);const g=c.useCallback(()=>{s.startQuestion(),o()},[s,o]),h=c.useCallback(()=>{s.nextPhase(),o()},[s,o]);return{state:l,startQuestion:g,nextPhase:h,timerService:s}}function ge(t,r={}){const[e,a]=c.useState({data:null,loading:!1,error:null}),s=c.useCallback(async(...l)=>{var n,o,g,h;a(u=>({...u,loading:!0,error:null}));try{const u=await t(...l);a(m=>({...m,data:u,loading:!1,error:null})),(n=r.onSuccess)==null||n.call(r,u),(o=r.onSettled)==null||o.call(r,u,null)}catch(u){const m=u.type?u:{type:"unknown",message:u.message||"Unknown error",retryable:!0,userMessage:"Something went wrong. Please try again.",originalError:u};a(f=>({...f,loading:!1,error:m})),(g=r.onError)==null||g.call(r,m),(h=r.onSettled)==null||h.call(r,null,m)}},[t,r]);return{...e,execute:s}}function he(t){var r;if(!navigator.onLine)return{type:"network",message:"No internet connection",retryable:!0,userMessage:"Please check your internet connection and try again."};if(t.name==="AbortError"||(r=t.message)!=null&&r.includes("timeout"))return{type:"timeout",message:"Request timed out",retryable:!0,userMessage:"The request is taking longer than expected. Please try again."};if(t.status){const{status:e}=t;if(e===401||e===403)return{type:"auth",status:e,message:"Authentication failed",retryable:!1,userMessage:"Your session has expired. Please refresh the page."};if(e===429)return{type:"rate-limit",status:e,message:"Too many requests",retryable:!0,userMessage:"Please wait a moment before trying again."};if(e>=500)return{type:"server",status:e,message:`Server error: ${e}`,retryable:!0,userMessage:"Our servers are experiencing issues. Please try again in a few moments."};if(e>=400)return{type:"client",status:e,message:`Client error: ${e}`,retryable:!1,userMessage:"There was an issue with your request. Please check your input."}}return{type:"unknown",message:t.message||"Unknown error occurred",retryable:!0,userMessage:"Something unexpected happened. Please try again.",originalError:t}}async function F(t,r={},e={attempts:3,backoff:"exponential",baseDelay:1e3,maxDelay:1e4,jitter:!0}){let a;for(let s=1;s<=e.attempts;s++)try{const l=new AbortController,n=setTimeout(()=>l.abort(),6e4),o=await fetch(t,{...r,signal:l.signal});if(clearTimeout(n),o.status>=400&&o.status<500&&o.status!==429)return o;if(!o.ok)throw new Error(`HTTP ${o.status}: ${o.statusText}`);return o}catch(l){a=l;const n=he(l);if(!n.retryable||s===e.attempts)throw n;const o=fe(s,e);console.warn(`API request failed (attempt ${s}/${e.attempts}), retrying in ${o}ms:`,n.message),await new Promise(g=>setTimeout(g,o))}throw a}function fe(t,r){let e;return r.backoff==="exponential"?e=r.baseDelay*Math.pow(2,t-1):e=r.baseDelay,e=Math.min(e,r.maxDelay),r.jitter&&(e=e*(.5+Math.random()*.5)),Math.round(e)}class xe{constructor(r={}){v(this,"config");this.config=r}updateConfig(r){this.config={...this.config,...r}}getHeaders(){var e;const r={"Content-Type":"application/json","X-Auth-Token":"appkey"};return(e=this.config)!=null&&e.authToken&&(r.Authorization=`Bearer ${this.config.authToken}`),r}getBaseUrl(){var r;return((r=this.config)==null?void 0:r.baseUrl)||"/api"}async generateQuestion({interviewId:r,isInterviewDone:e=!1,qnaId:a,question:s,answer:l,answerDuration:n}){const o=await F(`${this.getBaseUrl()}/interview/generate-question`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({interview_id:r,is_interview_done:e,qna_id:a,question:s,answer:l,answer_duration:n??"00:00:30"})});if(!o.ok)throw new Error(`Failed to get questions: ${o.status}`);return await o.json()}}function pe(){const t=$();return c.useMemo(()=>{const e=t.api||{};return new xe(e)},[t.api])}class b extends Error{constructor(r,e,a=!1){super(r),this.code=e,this.recoverable=a,this.name="STTError"}}class be{constructor(r={}){v(this,"config");v(this,"mediaRecorder",null);v(this,"audioChunks",[]);v(this,"recordingStream",null);v(this,"autoStopTimeoutId",null);this.config={baseUrl:"http://localhost:8000",provider:"groq",model:"whisper-large-v3-turbo",language:"en",includeTimestamps:!1,temperature:0,...r}}updateConfig(r){this.config={...this.config,...r}}isRecordingSupported(){return!!(navigator.mediaDevices&&typeof navigator.mediaDevices.getUserMedia=="function"&&window.MediaRecorder)}async startRecording(r,e){var a;if(!this.isRecordingSupported())throw new b("Audio recording is not supported in this browser","RECORDING_NOT_SUPPORTED",!1);if(this.isRecording())throw new b("Recording is already in progress","ALREADY_RECORDING",!0);try{this.recordingStream=await navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,sampleRate:44100}}),this.audioChunks=[];const s=this.getSupportedMimeType();this.mediaRecorder=new MediaRecorder(this.recordingStream,{mimeType:s}),this.mediaRecorder.ondataavailable=l=>{var n;l.data.size>0&&(this.audioChunks.push(l.data),(n=e==null?void 0:e.onDataAvailable)==null||n.call(e,l.data))},this.mediaRecorder.onstop=()=>{var l;(l=e==null?void 0:e.onStop)==null||l.call(e)},this.mediaRecorder.onerror=l=>{var o;const n=new b(`Recording failed: ${l.error}`,"RECORDING_ERROR",!0);(o=e==null?void 0:e.onError)==null||o.call(e,n),this.cleanup()},this.mediaRecorder.start(100),(a=e==null?void 0:e.onStart)==null||a.call(e),r&&r>0&&(this.autoStopTimeoutId=setTimeout(()=>{this.isRecording()&&this.stopRecording()},r*1e3))}catch(s){if(this.cleanup(),s instanceof Error){if(s.name==="NotAllowedError"||s.name==="PermissionDeniedError")throw new b("Microphone permission was denied","PERMISSION_DENIED",!1);if(s.name==="NotFoundError")throw new b("No microphone found","NO_MICROPHONE",!1)}throw new b(`Failed to start recording: ${s instanceof Error?s.message:String(s)}`,"START_RECORDING_FAILED",!0)}}async stopRecording(){if(this.autoStopTimeoutId&&(clearTimeout(this.autoStopTimeoutId),this.autoStopTimeoutId=null),!this.mediaRecorder||!this.isRecording())throw new b("No active recording to stop","NO_ACTIVE_RECORDING",!1);return new Promise((r,e)=>{if(!this.mediaRecorder){e(new b("MediaRecorder is null","MEDIARECORDER_NULL",!1));return}const a=this.mediaRecorder,s=()=>{try{const l=a.mimeType||"audio/webm",n=new Blob(this.audioChunks,{type:l});this.cleanup(),r(n)}catch(l){e(new b(`Failed to create audio blob: ${l instanceof Error?l.message:String(l)}`,"BLOB_CREATION_FAILED",!1))}};a.addEventListener("stop",s,{once:!0}),a.stop()})}async transcribe(r){const{audioBlob:e,model:a=this.config.model,language:s=this.config.language,includeTimestamps:l=this.config.includeTimestamps,temperature:n=this.config.temperature}=r;if(!e||e.size===0)throw new b("Audio blob is empty or invalid","INVALID_AUDIO",!1);try{const o=new FormData,g=new File([e],"recording.wav",{type:e.type||"audio/wav"});o.append("file",g),o.append("model",a||"whisper-large-v3-turbo"),o.append("language",s||"en"),o.append("include_timestamps",String(l||!1)),o.append("temperature",String(n||0));const h=await F(`${this.config.baseUrl}/speech/transcribe`,{method:"POST",headers:{accept:"application/json","X-STT-Provider":this.config.provider||"groq"},body:o},{attempts:1,backoff:"exponential",baseDelay:1e3,maxDelay:3e3,jitter:!0});if(!h.ok){const m=await h.text();let f=`STT request failed: ${h.status} ${h.statusText}`;try{const p=JSON.parse(m);f=p.message||p.error||f}catch{f=m||f}throw new b(f,`HTTP_${h.status}`,h.status>=500)}return{transcript:(await h.json()).data.text??""}}catch(o){throw o instanceof b?o:new b(`Transcription failed: ${o instanceof Error?o.message:String(o)}`,"TRANSCRIPTION_FAILED",!0)}}cancelRecording(){this.autoStopTimeoutId&&(clearTimeout(this.autoStopTimeoutId),this.autoStopTimeoutId=null),this.mediaRecorder&&this.isRecording()&&this.mediaRecorder.stop(),this.cleanup()}isRecording(){return this.mediaRecorder!==null&&this.mediaRecorder.state==="recording"}getSupportedMimeType(){const r=["audio/webm","audio/webm;codecs=opus","audio/ogg;codecs=opus","audio/mp4","audio/wav"];for(const e of r)if(MediaRecorder.isTypeSupported(e))return e;return"audio/webm"}cleanup(){this.recordingStream&&(this.recordingStream.getTracks().forEach(r=>r.stop()),this.recordingStream=null),this.mediaRecorder=null,this.audioChunks=[],this.autoStopTimeoutId&&(clearTimeout(this.autoStopTimeoutId),this.autoStopTimeoutId=null)}}const G=new be,ye=(t={})=>{const[r,e]=c.useState(!1),[a,s]=c.useState(!1),[l,n]=c.useState(null),[o,g]=c.useState(null),[h,u]=c.useState(null);t.config&&G.updateConfig(t.config);const m=c.useCallback(async S=>{var T;try{g(null),n(null),u(null),await G.startRecording(S,{onStart:()=>{var w;e(!0),(w=t.onStart)==null||w.call(t)},onStop:()=>{var w;e(!1),(w=t.onStop)==null||w.call(t)},onError:w=>{var I;const y=w instanceof b?w:new b(w.message,"RECORDING_ERROR",!0);g(y),e(!1),(I=t.onError)==null||I.call(t,y)}})}catch(w){const y=w instanceof b?w:new b(w instanceof Error?w.message:String(w),"START_FAILED",!1);throw g(y),e(!1),(T=t.onError)==null||T.call(t,y),y}},[]),f=c.useCallback(async()=>{var S,T;try{const w=await G.stopRecording();return u(w),e(!1),(S=t.onStop)==null||S.call(t),w}catch(w){const y=w instanceof b?w:new b(w instanceof Error?w.message:String(w),"STOP_FAILED",!1);throw g(y),e(!1),(T=t.onError)==null||T.call(t,y),y}},[]),p=c.useCallback(async(S,T={})=>{var w,y;try{g(null),s(!0);const I={audioBlob:S,...T},R=await G.transcribe(I);return n(R.transcript),s(!1),(w=t.onTranscriptionComplete)==null||w.call(t,R),R}catch(I){const R=I instanceof b?I:new b(I instanceof Error?I.message:String(I),"TRANSCRIPTION_FAILED",!0);throw g(R),s(!1),(y=t.onError)==null||y.call(t,R),R}},[]),k=c.useCallback(()=>{G.cancelRecording(),e(!1),u(null)},[]);return{startRecording:m,stopRecording:f,transcribe:p,cancelRecording:k,isRecording:r,isTranscribing:a,transcript:l,error:o,audioBlob:h}};class Ne{constructor(r={}){v(this,"config");v(this,"currentAudio",null);this.config={baseUrl:"http://localhost:8000",provider:"piper",voice:"string",speed:1,...r}}updateConfig(r){this.config={...this.config,...r}}async synthesizeSpeech(r){const{text:e,voice:a=this.config.voice,speed:s=this.config.speed}=r,l=new URLSearchParams;l.append("text",e),l.append("voice",a||"string"),l.append("speed",(s==null?void 0:s.toString())||"1");const n=await F(`${this.config.baseUrl}/speech/synthesize`,{method:"POST",headers:{accept:"application/json","X-TTS-Provider":this.config.provider||"piper","Content-Type":"application/x-www-form-urlencoded"},body:l},{attempts:1,backoff:"fixed",baseDelay:1e3,maxDelay:1e3,jitter:!1});if(!n.ok)throw new Error(`TTS request failed: ${n.status} ${n.statusText}`);const o=n.headers.get("content-type");if(o&&o.includes("audio/"))return n.blob();try{const g=await n.json();throw new Error(`TTS Error: ${JSON.stringify(g)}`)}catch{throw new Error("TTS request failed with unknown error")}}async speak(r,e){var a,s;try{this.stop(),(a=e==null?void 0:e.onStart)==null||a.call(e);const l=await this.synthesizeSpeech(r),n=URL.createObjectURL(l);return this.currentAudio=new Audio(n),new Promise((o,g)=>{if(!this.currentAudio){g(new Error("Audio element not created"));return}const h=this.currentAudio;h.onended=()=>{var u;URL.revokeObjectURL(n),this.currentAudio=null,(u=e==null?void 0:e.onEnd)==null||u.call(e),o()},h.onerror=u=>{var f;URL.revokeObjectURL(n),this.currentAudio=null;const m=new Error(`Audio playback failed: ${u}`);(f=e==null?void 0:e.onError)==null||f.call(e,m),g(m)},h.play().catch(u=>{var f;URL.revokeObjectURL(n),this.currentAudio=null;const m=new Error(`Failed to play audio: ${u.message}`);(f=e==null?void 0:e.onError)==null||f.call(e,m),g(m)})})}catch(l){const n=l instanceof Error?l:new Error(`TTS Error: ${String(l)}`);throw(s=e==null?void 0:e.onError)==null||s.call(e,n),n}}stop(){this.currentAudio&&(this.currentAudio.pause(),this.currentAudio.currentTime=0,this.currentAudio=null)}isPlaying(){return this.currentAudio!==null&&!this.currentAudio.paused}}const Q=new Ne,Te=(t={})=>{const[r,e]=c.useState(!1),[a,s]=c.useState(!1),[l,n]=c.useState(null);t.config&&Q.updateConfig(t.config);const o=c.useCallback(async(h,u={})=>{var m;try{n(null),s(!0);const f={text:h,...u};await Q.speak(f,{onStart:()=>{var p;s(!1),e(!0),(p=t.onStart)==null||p.call(t)},onEnd:()=>{var p;e(!1),(p=t.onEnd)==null||p.call(t)},onError:p=>{var k;e(!1),s(!1),n(p),(k=t.onError)==null||k.call(t,p)}})}catch(f){const p=f instanceof Error?f:new Error(String(f));throw n(p),e(!1),s(!1),(m=t.onError)==null||m.call(t,p),p}},[t]),g=c.useCallback(()=>{Q.stop(),e(!1),s(!1)},[]);return{speak:o,stop:g,isPlaying:r,isLoading:a,error:l}};function Ie(t){const r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return r?{r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16)}:null}function ve(t,r,e){return"#"+[t,r,e].map(a=>{const s=Math.round(a).toString(16);return s.length===1?"0"+s:s}).join("")}function J(t,r){const e=Ie(t);if(!e)return t;const a=e.r+(255-e.r)*r,s=e.g+(255-e.g)*r,l=e.b+(255-e.b)*r;return ve(a,s,l)}function Ee(t,r=.8){const e=J(t,r),a=J(t,.7);return{background:`linear-gradient(to bottom, ${e}, #ffffff)`,border:`1px solid ${a}`,color:"#1f2937"}}function Se(t){return new Promise(r=>setTimeout(r,t))}const je=({state:t,className:r="",defaultTimers:e={thinking:30,answering:120,editing:30}})=>{const a=u=>{const m=Math.floor(u/60),f=u%60;return`${m.toString().padStart(2,"0")}:${f.toString().padStart(2,"0")}`},s=u=>({[d.IDLE]:"Ready",[d.FETCHING_QUESTION]:"Loading Question...",[d.READING_QUESTION]:"Reading Question...",[d.THINKING]:"Preparation Time",[d.ANSWERING]:"Recording Answer",[d.TRANSCRIBING]:"Processing Speech...",[d.EDITING]:"Edit Your Answer",[d.SUBMITTING]:"Submitting...",[d.COMPLETED]:"Interview Complete"})[u]||u,l=u=>({[d.IDLE]:"iw-bg-gray-500",[d.FETCHING_QUESTION]:"iw-bg-blue-500",[d.READING_QUESTION]:"iw-bg-indigo-500",[d.THINKING]:"iw-bg-yellow-500",[d.ANSWERING]:"iw-bg-red-500",[d.TRANSCRIBING]:"iw-bg-purple-500",[d.EDITING]:"iw-bg-orange-500",[d.SUBMITTING]:"iw-bg-green-500",[d.COMPLETED]:"iw-bg-green-600"})[u]||"iw-bg-gray-500",n=u=>({[d.IDLE]:"iw-bg-gray-100 iw-text-gray-800",[d.FETCHING_QUESTION]:"iw-bg-blue-100 iw-text-blue-800",[d.READING_QUESTION]:"iw-bg-indigo-100 iw-text-indigo-800",[d.THINKING]:"iw-bg-yellow-100 iw-text-yellow-800",[d.ANSWERING]:"iw-bg-red-100 iw-text-red-800",[d.TRANSCRIBING]:"iw-bg-purple-100 iw-text-purple-800",[d.EDITING]:"iw-bg-orange-100 iw-text-orange-800",[d.SUBMITTING]:"iw-bg-green-100 iw-text-green-800",[d.COMPLETED]:"iw-bg-green-200 iw-text-green-900"})[u]||"iw-bg-gray-100 iw-text-gray-800",o=u=>({[d.IDLE]:"Ready to start next question.",[d.FETCHING_QUESTION]:"Please wait while we load the next question...",[d.READING_QUESTION]:"Listening to the question...",[d.THINKING]:"Take time to think about your answer.",[d.ANSWERING]:"Speak clearly into your microphone.",[d.TRANSCRIBING]:"Converting your speech to text...",[d.EDITING]:"Review and edit your answer.",[d.SUBMITTING]:"Submitting your answer...",[d.COMPLETED]:"Thank you for completing the interview!"})[u]||"";function g(u){return{[d.THINKING]:e.thinking||30,[d.ANSWERING]:e.answering||120,[d.EDITING]:e.editing||30}[u]||1}const h=t.currentPhaseTimeRemaining>0;return i.jsxs("div",{className:`iw-iw-bg-white iw-rounded-lg iw-shadow-md iw-p-4 iw-border iw-border-gray-200 ${r}`,children:[i.jsxs("div",{className:"iw-flex iw-justify-between iw-items-center iw-mb-4",children:[i.jsxs("div",{children:[i.jsx("h3",{className:"iw-text-sm iw-font-semibold iw-text-gray-700",children:"Interview Timer"}),i.jsxs("p",{className:"iw-text-xs iw-text-gray-700 iw-my-3 iw-font-mono",children:["Phase"," ",i.jsx("span",{className:`iw-px-3 iw-py-1.5 iw-rounded-md iw-font-medium ${n(t.phase)}`,children:t.phase})]}),i.jsxs("p",{className:"iw-text-xs iw-text-gray-700 iw-font-mono",children:["Question ",t.currentQuestionNumber]})]}),i.jsxs("div",{className:"iw-text-right",children:[i.jsx("div",{className:"iw-text-2xl iw-font-bold iw-text-gray-900",children:a(t.totalTimeRemaining)}),i.jsx("div",{className:"iw-text-xs iw-text-gray-500",children:"Total Time Left"})]})]}),i.jsx("div",{className:"iw-mb-4",children:i.jsx("div",{className:"iw-w-full iw-h-2 iw-iw-bg-gray-200 iw-rounded-full iw-overflow-hidden",children:i.jsx("div",{className:"iw-h-full iw-iw-bg-gradient-to-r iw-from-blue-500 iw-to-purple-500 iw-transition-all iw-duration-300",style:{width:`${t.totalTimeElapsed/(t.totalTimeElapsed+t.totalTimeRemaining)*100}%`}})})}),i.jsxs("div",{className:"iw-mb-4",children:[i.jsxs("div",{className:"iw-flex iw-items-center iw-justify-between iw-mb-2",children:[i.jsxs("div",{className:"iw-flex iw-items-center iw-space-x-2",children:[i.jsx("div",{className:`iw-w-3 iw-h-3 iw-rounded-full ${l(t.phase)} ${h?"iw-animate-pulse":""}`}),i.jsx("span",{className:"iw-text-sm iw-font-medium iw-text-gray-700",children:s(t.phase)})]}),h&&i.jsx("span",{className:"iw-text-lg iw-font-bold iw-text-gray-900",children:a(t.currentPhaseTimeRemaining)})]}),h&&i.jsx("div",{className:"iw-w-full iw-h-1.5 iw-iw-bg-gray-200 iw-rounded-full iw-overflow-hidden",children:i.jsx("div",{className:`iw-h-full ${l(t.phase)} iw-transition-all iw-duration-300`,style:{width:`${t.currentPhaseTimeRemaining/g(t.phase)*100}%`}})})]}),i.jsx("div",{className:"iw-mt-3 iw-pt-3 iw-border-t iw-border-gray-200",children:i.jsx("p",{className:"iw-text-xs iw-text-gray-600",children:o(t.phase)})})]})},Re=({label:t,error:r,fullWidth:e=!1,className:a="",id:s,...l})=>{const n=s||`textarea-${Math.random().toString(36).substring(2,9)}`,o="iw-block iw-rounded-md iw-border iw-border-gray-300 iw-shadow-sm iw-px-4 iw-py-2 iw-text-sm iw-focus:border-primary-500 iw-focus:ring-primary-500 iw-focus:outline-none iw-transition-all",g=r?"iw-border-red-500 iw-focus:border-red-500 iw-focus:ring-red-500":"",h=e?"iw-w-full":"",u=a.includes("iw-h-full")?"iw-h-full":"";return i.jsxs("div",{className:`${e?"iw-w-full iw-h-full":""} ${u?"iw-flex iw-flex-col":""}`,children:[t&&i.jsx("label",{htmlFor:n,className:"iw-block iw-text-sm iw-font-medium iw-text-gray-700 iw-mb-1",children:t}),i.jsx("textarea",{id:n,className:`${o} ${g} ${h} ${u} ${a}`,"aria-invalid":r?"true":"false",...l}),r&&i.jsx("p",{className:"iw-mt-1 iw-text-sm iw-text-red-600",children:r})]})},Ce=({value:t,onChange:r,onSubmit:e,isSubmitDisabled:a,remainingTimeText:s})=>{const l=n=>{n.key==="Enter"&&(n.ctrlKey||n.metaKey)&&!a&&(n.preventDefault(),e())};return i.jsx("div",{className:"iw-mt-auto",children:i.jsxs("div",{className:"iw-rounded-xl iw-overflow-hidden iw-border iw-border-gray-200",children:[i.jsxs("div",{className:"iw-flex iw-items-center iw-justify-between iw-px-3 iw-py-2 iw-bg-gray-50 iw-border-b iw-border-gray-200",children:[i.jsx("div",{className:"iw-text-sm iw-font-medium",children:"Your answer"}),s&&i.jsx("div",{className:"iw-text-xs iw-text-gray-500",children:s})]}),i.jsx(Re,{value:t,onChange:r,onKeyDown:l,placeholder:"Type your answer here...",className:"iw-bg-gray-50 iw-w-full iw-resize-none iw-focus:outline-none iw-bg-transparent iw-min-h-[112px]",rows:5,fullWidth:!0}),i.jsxs("div",{className:"iw-p-2 iw-flex iw-justify-between iw-items-center iw-bg-gray-50",children:[i.jsx("div",{className:"iw-text-xs iw-text-gray-500",children:i.jsx("kbd",{children:" Press Ctrl+Enter to submit"})}),i.jsx(A,{onClick:e,disabled:a,size:"sm",variant:"gradient",children:"Submit Answer"})]})]})})},ke=({question:t,isLoading:r=!1})=>{const{baseColor:e}=L();return r?i.jsxs("div",{className:"iw-rounded-xl iw-mb-4 iw-p-5",style:{background:"linear-gradient(to bottom, #eef2ff, #ffffff)",border:"1px solid #e0e7ff",color:"#1f2937"},children:[i.jsxs("div",{className:"iw-flex iw-items-center iw-space-x-3 iw-mb-3",children:[i.jsx("div",{className:"iw-h-12 iw-w-12 iw-rounded-lg iw-flex iw-items-center iw-justify-center iw-text-white iw-font-semibold iw-animate-pulse",style:{backgroundColor:e},children:"N"}),i.jsxs("div",{children:[i.jsx("div",{className:"iw-text-sm iw-font-semibold",children:"Novara"}),i.jsx("div",{className:"iw-text-xs iw-text-gray-500",children:"Assistant"})]})]}),i.jsxs("div",{className:"iw-animate-pulse",children:[i.jsx("div",{className:"iw-h-4 iw-bg-gray-200 iw-rounded iw-w-3/4 iw-mb-2"}),i.jsx("div",{className:"iw-h-4 iw-bg-gray-200 iw-rounded iw-w-full"})]})]}):t?i.jsxs("div",{className:"iw-rounded-xl iw-mb-4 message-animation iw-text-gray-800 iw-border iw-border-indigo-100 iw-p-5",style:Ee(e??"#8C75FB",.85),children:[i.jsxs("div",{className:"iw-flex iw-items-center iw-space-x-3 iw-mb-3",children:[i.jsx("div",{className:"iw-h-12 iw-w-12 iw-rounded-lg iw-flex iw-items-center iw-justify-center iw-text-white iw-font-semibold",style:{backgroundColor:e},children:"N"}),i.jsxs("div",{children:[i.jsx("div",{className:"iw-text-sm iw-font-semibold",children:"Novara"}),i.jsx("div",{className:"iw-text-xs iw-text-gray-500",children:"Assistant"})]})]}),i.jsx("p",{className:"iw-text-[15px] iw-leading-6",children:t.question})]}):i.jsx("div",{className:"iw-rounded-xl iw-mb-4 iw-bg-gray-50 iw-text-gray-500 iw-border iw-border-gray-200 iw-p-5 iw-text-center",children:i.jsx("p",{className:"iw-text-sm",children:"No question available"})})},Pe=({interviewId:t,onComplete:r,className:e=""})=>{const a=pe(),{baseColor:s}=L(),{baseUrl:l}=se(),{timers:n,stt:o,tts:g}=ne(),[h,u]=c.useState(null),[m,f]=c.useState(""),[p,k]=c.useState(!1),S=c.useRef(""),T=c.useRef(null),w={thinkingTime:(n==null?void 0:n.thinkingDuration)||30,answeringTime:(n==null?void 0:n.answeringDuration)||120,editingTime:(n==null?void 0:n.editingDuration)||30,totalTime:(n==null?void 0:n.totalInterviewDuration)||600,minimumBufferTime:(n==null?void 0:n.minimumTimeForNextQuestion)||120},{thinkingTime:y,answeringTime:I,editingTime:R,totalTime:De,minimumBufferTime:Ae}=w;c.useEffect(()=>{S.current=m},[m]);const U=c.useRef(!1),{speak:Ge,isPlaying:Me,error:V}=Te({config:{baseUrl:l,provider:g==null?void 0:g.provider},onEnd:()=>{console.log("TTS playback completed"),U.current=!1,E()},onError:x=>{console.error("TTS Error:",x),U.current||(U.current=!0,E())}}),M=c.useRef(!1),q=c.useRef(!1),{startRecording:X,stopRecording:Z,transcribe:ee,isRecording:Oe,isTranscribing:_e,error:O}=ye({config:{baseUrl:l,provider:o==null?void 0:o.provider,model:o==null?void 0:o.model,language:o==null?void 0:o.language},onStart:()=>{console.log("STT recording started"),M.current=!1,q.current=!1},onStop:()=>{console.log("STT recording stopped")},onTranscriptionComplete:x=>{console.log("Transcription completed:",x),f(x.transcript),q.current||(q.current=!0,E())},onError:x=>{console.error("STT Error:",x),M.current||(M.current=!0,E())}}),{state:C,startQuestion:H,nextPhase:E}=me({config:{thinkingDuration:y,answeringDuration:I,editingDuration:R,totalInterviewDuration:De,minimumTimeForNextQuestion:Ae},callbacks:{onPhaseChange:x=>{switch(console.log("Phase changed:",x),x){case d.FETCHING_QUESTION:$e();break;case d.READING_QUESTION:Ue();break;case d.ANSWERING:qe();break;case d.TRANSCRIBING:Fe();break;case d.SUBMITTING:Le();break}},onInterviewEnd:()=>{r==null||r()}}}),{execute:$e}=ge(async()=>{var D,ie;const x=await a.generateQuestion({interviewId:t,isInterviewDone:C.totalTimeRemaining<120,question:((D=T.current)==null?void 0:D.question)||"",qnaId:((ie=T.current)==null?void 0:ie.qna_id)||"",answer:S.current});return T.current=x.data,x},{onSuccess:async x=>{console.log("Questions fetched successfully",x),x&&x.data&&(f(""),u(x.data),E())},onError:x=>{console.error("Failed to fetch questions:",x)}}),Le=c.useCallback(async()=>{console.log("Answer submitted successfully"),await Se(1500),H()},[H]),Ue=c.useCallback(async()=>{var x;if((x=T.current)!=null&&x.question)try{U.current=!1,console.log("Starting TTS for question"),await Ge(T.current.question)}catch(D){console.error("Failed to speak question:",D)}else E()},[]),qe=c.useCallback(async()=>{console.log("Starting recording...");try{const x=I;console.log("🚀 ~ maxDuration:",x),await X(x)}catch(x){console.error("Failed to start recording:",x),E()}},[X,E]),Fe=c.useCallback(async()=>{console.log("Stopping recording and processing STT...");try{const x=await Z();console.log("Recording stopped, audio blob size:",x.size),await ee(x)}catch(x){console.error("STT processing failed:",x),!M.current&&!q.current&&(M.current=!0,E())}},[Z,ee,E]),Qe=()=>{const{phase:x}=C;switch(x){case d.IDLE:return i.jsx("div",{className:"iw-text-center iw-py-8",children:i.jsx("p",{className:"iw-text-gray-600",children:"Ready to start..."})});case d.FETCHING_QUESTION:return i.jsx("div",{className:"iw-space-y-4"});case d.READING_QUESTION:return i.jsx("div",{className:"iw-space-y-4",children:i.jsxs("div",{className:"iw-p-4 iw-bg-indigo-50 iw-border iw-border-indigo-200 iw-rounded-lg",children:[i.jsxs("div",{className:"iw-flex iw-items-center iw-space-x-2",children:[i.jsx("div",{className:"iw-w-3 iw-h-3 iw-bg-indigo-500 iw-rounded-full iw-animate-pulse"}),i.jsx("span",{className:"iw-text-sm iw-font-medium iw-text-indigo-700",children:Me?"Playing question audio...":"Reading the question..."})]}),V&&i.jsxs("div",{className:"iw-mt-2 iw-text-xs iw-text-red-600",children:["Audio playback failed: ",V.message]})]})});case d.THINKING:case d.ANSWERING:return i.jsx("div",{className:"iw-space-y-4",children:x===d.ANSWERING&&i.jsxs("div",{className:"iw-p-4 iw-bg-red-50 iw-border iw-border-red-200 iw-rounded-lg",children:[i.jsxs("div",{className:"iw-flex iw-items-center iw-space-x-2",children:[i.jsx("div",{className:"iw-w-3 iw-h-3 iw-bg-red-500 iw-rounded-full iw-animate-pulse"}),i.jsx("span",{className:"iw-text-sm iw-font-medium iw-text-red-700",children:Oe?"Recording in progress...":"Preparing to record..."})]}),O&&i.jsxs("div",{className:"iw-mt-2 iw-text-xs iw-text-red-600",children:["Recording error: ",O.message]})]})});case d.TRANSCRIBING:return i.jsx("div",{className:"iw-space-y-4",children:i.jsxs("div",{className:"iw-p-4 iw-bg-purple-50 iw-border iw-border-purple-200 iw-rounded-lg",children:[i.jsxs("div",{className:"iw-flex iw-items-center iw-space-x-2",children:[i.jsx("div",{className:"iw-animate-spin iw-h-4 iw-w-4 iw-border-2 iw-border-purple-500 iw-border-t-transparent iw-rounded-full"}),i.jsx("span",{className:"iw-text-sm iw-font-medium iw-text-purple-700",children:_e?"Transcribing your speech...":"Processing audio..."})]}),O&&i.jsxs("div",{className:"iw-mt-2 iw-text-xs iw-text-red-600",children:["Transcription error: ",O.message,O.recoverable&&" (attempting to continue)"]})]})});case d.EDITING:return i.jsx("div",{className:"iw-space-y-4",children:i.jsx(Ce,{value:m,onChange:D=>f(D.target.value),onSubmit:()=>E(),isSubmitDisabled:!m.trim(),remainingTimeText:`${C.currentPhaseTimeRemaining}s remaining`})});case d.SUBMITTING:return i.jsx("div",{className:"iw-space-y-4",children:i.jsx("div",{className:"iw-p-4 iw-bg-green-50 iw-border iw-border-green-200 iw-rounded-lg",children:i.jsxs("div",{className:"iw-flex iw-items-center iw-space-x-2",children:[i.jsx("div",{className:"iw-animate-spin iw-h-4 iw-w-4 iw-border-2 iw-border-green-500 iw-border-t-transparent iw-rounded-full"}),i.jsx("span",{className:"iw-text-sm iw-font-medium iw-text-green-700",children:"Submitting your answer..."})]})})});case d.COMPLETED:return i.jsxs("div",{className:"iw-text-center iw-py-8",children:[i.jsx("div",{className:"iw-mb-4",children:i.jsx("svg",{className:"iw-w-16 iw-h-16 iw-mx-auto iw-text-green-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:i.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"})})}),i.jsx("h3",{className:"iw-text-xl iw-font-bold iw-text-gray-900 iw-mb-2",children:"Interview Complete!"}),i.jsx("p",{className:"iw-text-gray-600",children:"Thank you for your time. Your answers have been recorded."})]});default:return null}};return i.jsx("div",{className:"interview-widget-container",children:i.jsxs("div",{className:` iw-max-w-3xl iw-mx-auto iw-space-y-4 iw-py-8 ${e}`,children:[C.phase!==d.IDLE&&C.phase!==d.COMPLETED&&i.jsx(ke,{question:h,isLoading:C.phase===d.FETCHING_QUESTION}),i.jsx("div",{className:"iw-bg-white iw-rounded-lg iw-shadow-md iw-p-6",children:Qe()}),i.jsx(je,{state:C,defaultTimers:{thinking:y,answering:I,editing:R}}),p&&(C.phase===d.THINKING||C.phase===d.ANSWERING||C.phase===d.EDITING)&&i.jsx(A,{onClick:E,children:"Next Phase"}),!p&&i.jsx("div",{className:"iw-text-center iw-py-12 w-full",children:i.jsx(A,{className:"w-full",style:{backgroundColor:s},onClick:()=>{H(),k(!0)},children:"Start Interview"})})]})})},B=({interviewId:t,title:r="Interview",onInterviewEnd:e,className:a=""})=>{const[s,l]=c.useState(!1),[n,o]=c.useState(!0),g=c.useRef(null);if(!s)return i.jsx("div",{className:"interview-widget-container",children:i.jsx(ce,{isOpen:n,onStart:()=>{console.log("Permissions granted, starting interview"),l(!0),o(!1)}})});const h=()=>{e==null||e()};return i.jsx("div",{className:"interview-widget-container",children:i.jsx("div",{ref:g,className:`iw-flex iw-flex-col iw-rounded-xl iw-shadow-lg iw-overflow-hidden iw-h-[calc(100vh-1rem)] ${a}`,children:i.jsxs("div",{className:" iw-h-full iw-flex iw-flex-col",children:[i.jsx(le,{title:r,onExit:h}),i.jsx(Pe,{interviewId:t,className:a,onComplete:e||(()=>{})})]})})})};typeof window<"u"&&(window.InterviewWidget={InterviewWidget:B,InterviewWidgetProvider:K}),N.InterviewWidget=B,N.InterviewWidgetProvider=K,N.default=B,Object.defineProperties(N,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "interview-widget",
3
3
  "type": "module",
4
- "version": "0.0.7",
4
+ "version": "0.0.9",
5
5
  "description": "Advanced React interview widget with STT, TTS, camera access, and ML-powered analysis",
6
6
  "main": "dist/widget.umd.js",
7
7
  "module": "dist/widget.es.js",