File size: 6,302 Bytes
dcecd20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI Blog Assistant</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
    <style>

        body {

            font-family: 'Inter', sans-serif;

        }

        .loader {

            border: 4px solid #f3f3f3;

            border-top: 4px solid #3b82f6;

            border-radius: 50%;

            width: 24px;

            height: 24px;

            animation: spin 1s linear infinite;

        }

        @keyframes spin {

            0% { transform: rotate(0deg); }

            100% { transform: rotate(360deg); }

        }

    </style>
</head>
<body class="bg-gray-100 flex items-center justify-center min-h-screen">
    <div class="w-full max-w-2xl bg-white rounded-2xl shadow-lg p-8 m-4">
        <div class="text-center mb-8">
            <h1 class="text-4xl font-bold text-gray-800">AI Blog Assistant</h1>
            <p class="text-gray-500 mt-2">Ask a question based on the provided documents to get help writing your blog.</p>
        </div>

        <!-- Query Form -->
        <div class="mb-6">
            <form id="query-form" class="flex flex-col sm:flex-row items-stretch gap-3">
                <input type="text" id="query-input" placeholder="e.g., How does the Augusta Rule work?" class="flex-grow w-full px-4 py-3 text-gray-700 bg-gray-50 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition duration-200" required>
                <button type="submit" id="submit-button" class="bg-blue-600 text-white font-semibold px-6 py-3 rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition duration-200 flex items-center justify-center gap-2">
                    <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-send"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
                    <span>Get Answer</span>
                </button>
            </form>
        </div>
        
        <!-- Error Message Area -->
        <div id="error-message" class="hidden bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-lg relative mb-6" role="alert">
            <strong class="font-bold">Error:</strong>
            <span class="block sm:inline" id="error-text"></span>
        </div>

        <!-- Response Area -->
        <div id="response-container" class="hidden">
            <h2 class="text-2xl font-semibold text-gray-800 mb-4">Answer:</h2>
            <div id="response-card" class="bg-gray-50 p-6 rounded-lg border border-gray-200 min-h-[100px] flex items-center">
                 <div id="loader" class="loader hidden"></div>
                 <p id="response-text" class="text-gray-700 leading-relaxed"></p>
            </div>
        </div>
        
        <div class="text-center mt-8">
            <p class="text-xs text-gray-400">RAG-Powered Web Interface</p>
        </div>
    </div>

    <script>

        const form = document.getElementById('query-form');

        const input = document.getElementById('query-input');

        const submitButton = document.getElementById('submit-button');

        const responseContainer = document.getElementById('response-container');

        const responseCard = document.getElementById('response-card');

        const responseText = document.getElementById('response-text');

        const loader = document.getElementById('loader');

        const errorMessage = document.getElementById('error-message');

        const errorText = document.getElementById('error-text');



        // IMPORTANT: In a real deployment (like Hugging Face), this URL should be relative.

        // The server and the frontend are served from the same origin.

        const API_URL = '/query';



        form.addEventListener('submit', async (e) => {

            e.preventDefault();

            const query = input.value.trim();

            if (!query) return;



            // --- UI Changes for Loading State ---

            submitButton.disabled = true;

            submitButton.classList.add('opacity-50', 'cursor-not-allowed');

            responseText.textContent = '';

            loader.classList.remove('hidden');

            responseContainer.classList.remove('hidden');

            errorMessage.classList.add('hidden'); // Hide previous errors



            try {

                const response = await fetch(API_URL, {

                    method: 'POST',

                    headers: { 'Content-Type': 'application/json' },

                    body: JSON.stringify({ query: query })

                });



                if (!response.ok) {

                    const errorData = await response.json().catch(() => ({}));

                    const errorMsg = errorData.error || `HTTP error! Status: ${response.status}`;

                    throw new Error(errorMsg);

                }



                const data = await response.json();

                responseText.textContent = data.answer;



            } catch (error) {

                console.error("Fetch error:", error);

                errorText.textContent = `Failed to process the query. Make sure the backend server is running and accessible. Details: ${error.message}`;

                errorMessage.classList.remove('hidden');

                responseContainer.classList.add('hidden'); // Hide the response area on error

            } finally {

                // --- Revert UI Changes ---

                submitButton.disabled = false;

                submitButton.classList.remove('opacity-50', 'cursor-not-allowed');

                loader.classList.add('hidden');

            }

        });

    </script>
</body>
</html>