{"id":2,"date":"2026-04-05T05:42:43","date_gmt":"2026-04-05T05:42:43","guid":{"rendered":"https:\/\/www.codeweaverstudio.com\/blog\/?page_id=2"},"modified":"2026-04-05T11:50:16","modified_gmt":"2026-04-05T11:50:16","slug":"home","status":"publish","type":"page","link":"https:\/\/www.codeweaverstudio.com\/blog\/","title":{"rendered":"Home"},"content":{"rendered":"    <div id=\"owc-doc-builder-root\"><\/div>\r\n    <script type=\"text\/babel\">\r\n        const { useState } = React;\r\n\r\n        function DocBuilderApp() {\r\n            const [generating, setGenerating] = useState(false);\r\n            const [error, setError] = useState(null);\r\n            const [result, setResult] = useState(null);\r\n            const [formData, setFormData] = useState({\r\n                destination: '', nationality: '', arrival: '', departure: '', status: 'Employed', purpose: ''\r\n            });\r\n\r\n            const handleGenerate = async (e) => {\r\n                e.preventDefault();\r\n                setGenerating(true);\r\n                setError(null);\r\n\r\n                try {\r\n                    const response = await fetch(owcApiSettings.root + 'owc-builder\/v1\/generate', {\r\n                        method: 'POST',\r\n                        headers: {\r\n                            'Content-Type': 'application\/json',\r\n                            'X-WP-Nonce': owcApiSettings.nonce\r\n                        },\r\n                        body: JSON.stringify(formData)\r\n                    });\r\n\r\n                    if (!response.ok) throw new Error(\"Failed to generate. Please try again.\");\r\n                    \r\n                    const data = await response.json();\r\n                    setResult(data);\r\n                } catch (err) {\r\n                    setError(err.message);\r\n                } finally {\r\n                    setGenerating(false);\r\n                }\r\n            };\r\n\r\n            const handleDownload = () => {\r\n                if (!result) return;\r\n                let content = `# VISA APPLICATION COVER LETTER\\n\\n${result.cover_letter}\\n\\n---\\n\\n# DAY-BY-DAY ITINERARY\\n\\n`;\r\n                result.itinerary.forEach(item => { content += `**Day ${item.day} (${item.date}):** ${item.activities}\\n\\n`; });\r\n                const blob = new Blob([content], { type: 'text\/markdown' });\r\n                const a = document.createElement('a');\r\n                a.href = URL.createObjectURL(blob);\r\n                a.download = `Visa_Documents_${formData.destination}.md`;\r\n                a.click();\r\n            };\r\n\r\n            return (\r\n                <div className=\"font-sans text-slate-800 bg-slate-50 p-6 rounded-2xl border border-slate-200\">\r\n                    <h2 className=\"text-2xl font-bold mb-6 text-blue-800\">Embassy-Ready Document Builder<\/h2>\r\n                    <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-8\">\r\n                        {\/* Form Area *\/}\r\n                        <div className=\"bg-white p-6 rounded-xl shadow-sm border border-slate-200\">\r\n                            <form onSubmit={handleGenerate} className=\"space-y-4\">\r\n                                <div className=\"grid grid-cols-2 gap-4\">\r\n                                    <div><label className=\"block text-sm font-medium text-slate-700 mb-1\">Destination<\/label><input type=\"text\" onChange={e => setFormData({...formData, destination: e.target.value})} required className=\"w-full p-2.5 border rounded-lg\" \/><\/div>\r\n                                    <div><label className=\"block text-sm font-medium text-slate-700 mb-1\">Nationality<\/label><input type=\"text\" onChange={e => setFormData({...formData, nationality: e.target.value})} required className=\"w-full p-2.5 border rounded-lg\" \/><\/div>\r\n                                <\/div>\r\n                                <div className=\"grid grid-cols-2 gap-4\">\r\n                                    <div><label className=\"block text-sm font-medium text-slate-700 mb-1\">Arrival<\/label><input type=\"date\" onChange={e => setFormData({...formData, arrival: e.target.value})} required className=\"w-full p-2.5 border rounded-lg\" \/><\/div>\r\n                                    <div><label className=\"block text-sm font-medium text-slate-700 mb-1\">Departure<\/label><input type=\"date\" onChange={e => setFormData({...formData, departure: e.target.value})} required className=\"w-full p-2.5 border rounded-lg\" \/><\/div>\r\n                                <\/div>\r\n                                <div>\r\n                                    <label className=\"block text-sm font-medium text-slate-700 mb-1\">Employment Status<\/label>\r\n                                    <select onChange={e => setFormData({...formData, status: e.target.value})} className=\"w-full p-2.5 border rounded-lg\">\r\n                                        <option>Employed<\/option><option>Self-Employed \/ Business Owner<\/option><option>Student<\/option><option>Retired<\/option>\r\n                                    <\/select>\r\n                                <\/div>\r\n                                <div>\r\n                                    <label className=\"block text-sm font-medium text-slate-700 mb-1\">Purpose of Travel<\/label>\r\n                                    <textarea rows=\"2\" onChange={e => setFormData({...formData, purpose: e.target.value})} required className=\"w-full p-2.5 border rounded-lg\"><\/textarea>\r\n                                <\/div>\r\n                                {error && <div className=\"p-3 bg-red-50 text-red-700 text-sm rounded-lg\">{error}<\/div>}\r\n                                <button type=\"submit\" disabled={generating} className={`w-full py-3 rounded-lg font-semibold text-white transition-all ${generating ? 'bg-blue-400' : 'bg-blue-600 hover:bg-blue-700'}`}>\r\n                                    {generating ? 'Generating Documents...' : 'Generate Embassy-Ready Documents'}\r\n                                <\/button>\r\n                            <\/form>\r\n                        <\/div>\r\n\r\n                        {\/* Results Area *\/}\r\n                        <div className=\"bg-slate-900 rounded-xl p-6 flex flex-col text-slate-200\">\r\n                            {!result ? (\r\n                                <div className=\"flex-1 flex items-center justify-center text-slate-500\">Awaiting applicant details...<\/div>\r\n                            ) : (\r\n                                <div className=\"h-full flex flex-col\">\r\n                                    <div className=\"flex justify-between items-center mb-4\">\r\n                                        <h3 className=\"font-semibold text-white text-lg\">Generation Complete<\/h3>\r\n                                        <button onClick={handleDownload} className=\"bg-blue-600 hover:bg-blue-500 text-white px-3 py-1.5 rounded-lg text-sm\">Download .md File<\/button>\r\n                                    <\/div>\r\n                                    <div className=\"bg-slate-800 rounded-lg p-4 flex-1 overflow-y-auto text-sm font-mono leading-relaxed max-h-[500px]\">\r\n                                        <p className=\"text-blue-400 font-bold mb-2\"># COVER_LETTER<\/p>\r\n                                        <p className=\"whitespace-pre-wrap\">{result.cover_letter}<\/p>\r\n                                        <div className=\"border-t border-slate-700 mt-4 pt-4\">\r\n                                            <p className=\"text-blue-400 font-bold mb-2\"># ITINERARY<\/p>\r\n                                            {result.itinerary.map((item, idx) => (\r\n                                                <p key={idx} className=\"mb-2\"><strong>Day {item.day} ({item.date}):<\/strong> {item.activities}<\/p>\r\n                                            ))}\r\n                                        <\/div>\r\n                                    <\/div>\r\n                                <\/div>\r\n                            )}\r\n                        <\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            );\r\n        }\r\n\r\n        const root = ReactDOM.createRoot(document.getElementById('owc-doc-builder-root'));\r\n        root.render(<DocBuilderApp \/>);\r\n    <\/script>\r\n    \n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2","page","type-page","status-publish"],"_links":{"self":[{"href":"https:\/\/www.codeweaverstudio.com\/blog\/wp-json\/wp\/v2\/pages\/2","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codeweaverstudio.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.codeweaverstudio.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.codeweaverstudio.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codeweaverstudio.com\/blog\/wp-json\/wp\/v2\/comments?post=2"}],"version-history":[{"count":3,"href":"https:\/\/www.codeweaverstudio.com\/blog\/wp-json\/wp\/v2\/pages\/2\/revisions"}],"predecessor-version":[{"id":21,"href":"https:\/\/www.codeweaverstudio.com\/blog\/wp-json\/wp\/v2\/pages\/2\/revisions\/21"}],"wp:attachment":[{"href":"https:\/\/www.codeweaverstudio.com\/blog\/wp-json\/wp\/v2\/media?parent=2"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}