CoolFace
Apppublic

3emibrahim/debugging-testing2

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
text-generator.html681 linesDownload Raw Back to frontend
1<!DOCTYPE html>2<html lang="en">3  <head>4    <meta charset="UTF-8" />5    <meta name="viewport" content="width=device-width, initial-scale=1.0" />6    <title>AIToolkit - Text Generator</title>7    <style>8      :root {9        --primary: #4f46e5;10        --primary-dark: #4338ca;11        --secondary: #10b981;12        --accent: #f97316;13        --light: #f3f4f6;14        --dark: #1f2937;15        --gray: #9ca3af;16      }17 18      * {19        margin: 0;20        padding: 0;21        box-sizing: border-box;22        font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;23      }24 25      body {26        background-color: #f9fafb;27        color: var(--dark);28        line-height: 1.6;29      }30 31      header {32        background-color: white;33        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);34        padding: 1rem 2rem;35        position: sticky;36        top: 0;37        z-index: 10;38      }39 40      nav {41        display: flex;42        justify-content: space-between;43        align-items: center;44        max-width: 1200px;45        margin: 0 auto;46      }47 48      .logo {49        font-size: 1.5rem;50        font-weight: 700;51        color: var(--primary);52        display: flex;53        align-items: center;54        gap: 0.5rem;55      }56 57      .nav-links {58        display: flex;59        gap: 2rem;60      }61 62      .nav-links a {63        text-decoration: none;64        color: var(--dark);65        font-weight: 500;66        transition: color 0.2s;67      }68 69      .nav-links a:hover {70        color: var(--primary);71      }72 73      main {74        max-width: 1200px;75        margin: 0 auto;76        padding: 2rem;77      }78 79      .page-title {80        text-align: center;81        margin-bottom: 3rem;82      }83 84      .page-title h1 {85        font-size: 2.5rem;86        color: var(--dark);87        margin-bottom: 1rem;88      }89 90      .page-title p {91        font-size: 1.2rem;92        color: var(--gray);93        max-width: 700px;94        margin: 0 auto;95      }96 97      .text-generator-container {98        background-color: white;99        border-radius: 0.75rem;100        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);101        padding: 2rem;102        margin-bottom: 2rem;103        display: flex;104        gap: 2rem;105        max-width: 1800px;106        width: 100%;107        margin-left: auto;108        margin-right: auto;109        min-height: 200px; /* Increased height */110      }111 112      .conversation-section {113        flex: 1.5;114        display: flex;115        flex-direction: column;116      }117 118      .media-section {119        flex: 0.9;120        border-left: 1px solid #e5e7eb;121        padding-left: 2rem;122      }123 124      .conversation-history {125        flex: 1;126        overflow-y: auto;127        background-color: var(--light);128        border-radius: 0.5rem;129        padding: 1rem;130        margin-bottom: 1rem;131        max-height: 380px; /* Increased height */132      }133 134      .message {135        margin-bottom: 1rem;136        padding: 0.75rem;137        border-radius: 0.5rem;138        word-wrap: break-word;139        overflow-wrap: break-word;140        width: auto;141        display: inline-block;142        max-width: 80%;143      }144 145      .user-message {146        background-color: #e2e8f0;147        text-align: right;148        float: right;149        clear: both;150      }151 152      .ai-message {153        background-color: #dbeafe;154        float: left;155        clear: both;156      }157 158      .input-area {159        display: flex;160        gap: 1rem;161      }162 163      .input-area textarea {164        flex: 1;165        min-height: 60px;166        resize: none;167        padding: 0.75rem;168        border: 1px solid #e5e7eb;169        border-radius: 0.5rem;170        font-size: 1rem;171      }172 173      .send-btn {174        background-color: var(--primary);175        color: white;176        border: none;177        border-radius: 0.5rem;178        padding: 0 1rem;179        font-size: 1rem;180        font-weight: 500;181        cursor: pointer;182        transition: background-color 0.2s;183      }184 185      .send-btn:hover {186        background-color: var(--primary-dark);187      }188 189      .media-controls {190        display: flex;191        flex-direction: column;192        gap: 1rem;193        margin-bottom: 1.5rem;194      }195 196      .media-upload {197        display: flex;198        gap: 1rem;199        align-items: center;200      }201 202      .upload-btn {203        background-color: var(--secondary);204        color: white;205        border: none;206        border-radius: 0.5rem;207        padding: 0.75rem 1rem;208        font-size: 1rem;209        font-weight: 500;210        cursor: pointer;211        transition: background-color 0.2s;212        flex-shrink: 0; /* Prevent button from shrinking */213      }214 215      .upload-btn:hover {216        background-color: #0ca678;217      }218 219      .file-name-container {220        overflow: hidden;221        text-overflow: ellipsis;222        white-space: nowrap;223        max-width: 200px; /* Limit the width of the filename */224      }225 226      .media-preview {227        background-color: var(--light);228        border-radius: 0.5rem;229        min-height: 380px; /* Increased height */230        display: flex;231        flex-direction: column; /* Change to column to allow for size info below */232        align-items: center;233        justify-content: center;234        overflow: hidden;235        position: relative; /* For positioning the size info */236        padding: 1rem;237      }238 239      .media-preview img,240      .media-preview video {241        max-width: 100%;242        max-height: 300px; /* Limit the height of media */243        object-fit: contain;244      }245 246      .media-info {247        margin-top: 0.5rem;248        font-size: 0.875rem;249        color: var(--gray);250        text-align: center;251        background-color: rgba(255, 255, 255, 0.8);252        padding: 0.25rem 0.5rem;253        border-radius: 0.25rem;254        width: 100%;255      }256 257      .options-panel {258        margin-bottom: 1rem;259      }260 261      .options-panel h3 {262        margin-bottom: 0.75rem;263      }264 265      .input-row {266        display: flex;267        gap: 1rem;268        margin-bottom: 1rem;269      }270 271      .input-row > div {272        flex: 1;273      }274 275      .input-section label {276        display: block;277        margin-bottom: 0.5rem;278        font-weight: 500;279      }280 281      .input-section select {282        width: 100%;283        padding: 0.75rem;284        border: 1px solid #e5e7eb;285        border-radius: 0.5rem;286        font-size: 1rem;287      }288 289      .hidden {290        display: none;291      }292 293      @media (max-width: 968px) {294        .text-generator-container {295          flex-direction: column;296        }297 298        .media-section {299          border-left: none;300          border-top: 1px solid #e5e7eb;301          padding-left: 0;302          padding-top: 2rem;303        }304      }305 306      @media (max-width: 768px) {307        .input-row {308          flex-direction: column;309          gap: 1rem;310        }311 312        .nav-links {313          display: none;314        }315      }316 317      .copyright {318        text-align: center;319        padding: 1.5rem 0;320        background-color: #374151;321        color: var(--gray);322        margin-top: 2rem;323        font-size: 0.9rem;324        border-top: 1px solid #374151;325      }326 327      .copyright p {328        max-width: 1200px;329        margin: 0 auto;330      }331    </style>332  </head>333  <body>334    <header>335      <nav>336        <div class="logo">337          <span>AIToolkit</span>338        </div>339        <div class="nav-links">340          <a href="/">Home</a>341          <a href="/features">Features</a>342          <a href="/contact">Contact us</a>343          <a href="/about">About</a>344        </div>345      </nav>346    </header>347 348    <main>349      <div class="text-generator-container">350        <!-- Left column: Conversation interface -->351        <div class="conversation-section">352          <div class="options-panel">353            <h3>Content Options</h3>354            <div class="input-row">355              <div class="input-section"></div>356              <div class="input-section"></div>357            </div>358          </div>359 360          <div class="conversation-history" id="conversation-history">361            <div class="message ai-message">362              Hello! Ask me anything about that?363            </div>364          </div>365 366          <div class="input-area">367            <textarea368              id="user-input"369              placeholder="Type your message here..."370            ></textarea>371            <button class="send-btn" onclick="sendMessage()">Send</button>372          </div>373        </div>374 375        <!-- Right column: Media display -->376        <div class="media-section">377          <h2>Media</h2>378          <div class="media-controls">379            <div class="media-upload">380              <input381                type="file"382                id="media-file"383                class="hidden"384                accept="image/*,.pdf,.txt,.pptx,.xlsx"385                onchange="handleFileUpload()"386              />387              <button388                class="upload-btn"389                onclick="document.getElementById('media-file').click()"390              >391                Upload Media392              </button>393              <div class="file-name-container">394                <span id="file-name">No file chosen</span>395              </div>396            </div>397          </div>398          <div class="media-preview" id="media-preview">399            <p>Your uploaded media will appear here...</p>400          </div>401        </div>402      </div>403    </main>404 405    <footer class="copyright">406      <p>&copy; 2025 AIToolkit. All rights reserved.</p>407    </footer>408 409    <script>410      async function sendMessage() {411        const userInput = document.getElementById("user-input").value;412        const conversationHistory = document.getElementById(413          "conversation-history"414        );415        const fileInput = document.getElementById("media-file");416 417        if (!userInput.trim()) {418          alert("Please enter a message.");419          return;420        }421 422        // Add user message to the conversation423        const userMessageDiv = document.createElement("div");424        userMessageDiv.className = "message user-message";425        userMessageDiv.textContent = userInput;426        conversationHistory.appendChild(userMessageDiv);427 428        // Clear input field429        document.getElementById("user-input").value = "";430 431        // Add loading message432        const loadingMessage = document.createElement("div");433        loadingMessage.className = "message ai-message";434        loadingMessage.textContent = "Processing your request...";435        conversationHistory.appendChild(loadingMessage);436 437        try {438          // Create form data (works for both file and text-only cases)439          const formData = new FormData();440          formData.append("user_prompt", userInput);441 442          if (fileInput.files.length > 0) {443            formData.append("file", fileInput.files[0]);444          } else {445            formData.append("file", new File([""], "empty.txt"));446          }447 448          const response = await fetch("/process/", {449            method: "POST",450            body: formData,451          });452 453          // Remove loading message454          conversationHistory.removeChild(loadingMessage);455 456          if (!response.ok) {457            throw new Error("Failed to fetch response from the server.");458          }459 460          const data = await response.json();461          const aiMessageDiv = document.createElement("div");462          aiMessageDiv.className = "message ai-message";463 464          // Format the response with HTML465          const formattedResponse = formatAIResponse(data.response);466          aiMessageDiv.innerHTML = formattedResponse;467 468          conversationHistory.appendChild(aiMessageDiv);469        } catch (error) {470          console.error("Error:", error);471          conversationHistory.removeChild(loadingMessage);472 473          const errorMessageDiv = document.createElement("div");474          errorMessageDiv.className = "message ai-message error-message";475          errorMessageDiv.textContent = "Error: " + error.message;476          conversationHistory.appendChild(errorMessageDiv);477        }478 479        // Scroll to the latest message480        conversationHistory.scrollTop = conversationHistory.scrollHeight;481      }482 483      // Helper function to format the AI response484      function formatAIResponse(text) {485        // Escape HTML first for security486        let formatted = text.replace(/</g, "&lt;").replace(/>/g, "&gt;");487 488        // Convert line breaks to <br>489        formatted = formatted.replace(/\n/g, "<br>");490 491        // Better handling for bullet points with proper list nesting492        // Look for bullet patterns (• or * or -) followed by space493        formatted = formatted.replace(494          /(?:<br>)?(•|\*|\-) (.*?)(?:<br>|$)/g,495          "<ul>$2</ul>"496        );497 498        // If we found any list items, wrap them in a <ul>499        if (formatted.includes("<ul>")) {500          // Group consecutive list items into a single <ul>501          formatted = formatted.replace(502            /(<ul>.*?<\/ul>)(?:<br>)?/g,503            "<ul>$1</ul>"504          );505 506          // Clean up any adjacent <ul> tags that might have been created507          formatted = formatted.replace(/<\/ul><ul>/g, "");508        }509 510        // Improved pattern for bold headings like "**Setting:**"511        formatted = formatted.replace(512          /\*\*(.*?)\*\*:/g,513          "<strong>$1:</strong>"514        );515 516        return formatted;517      }518 519      function handleFileUpload() {520        const fileInput = document.getElementById("media-file");521        const preview = document.getElementById("media-preview");522        const fileName = document.getElementById("file-name");523        524        if (fileInput.files && fileInput.files[0]) {525          const file = fileInput.files[0];526          const fileType = file.type;527          const fileExtension = file.name.split('.').pop().toLowerCase();528          529          // Truncate long filenames530          if (file.name.length > 20) {531            const extension = file.name.split(".").pop();532            const nameWithoutExt = file.name.substring(0, file.name.lastIndexOf("."));533            fileName.textContent =534              nameWithoutExt.substring(0, 10) +535              "..." +536              nameWithoutExt.substring(nameWithoutExt.length - 5) +537              "." +538              extension;539          } else {540            fileName.textContent = file.name;541          }542          543          const reader = new FileReader();544          545          reader.onload = function (e) {546            preview.innerHTML = "";547            548            // Handle different file types549            if (fileType.startsWith("image/")) {550              const img = document.createElement("img");551              img.src = e.target.result;552              preview.appendChild(img);553              554              img.onload = function () {555                const infoDiv = document.createElement("div");556                infoDiv.className = "media-info";557                infoDiv.textContent = `Size: ${img.naturalWidth}×${img.naturalHeight}px | File size: ${formatFileSize(file.size)}`;558                preview.appendChild(infoDiv);559              };560            } else if (fileType.startsWith("video/")) {561              const video = document.createElement("video");562              video.src = e.target.result;563              video.controls = true;564              preview.appendChild(video);565              566              video.onloadedmetadata = function () {567                const infoDiv = document.createElement("div");568                infoDiv.className = "media-info";569                infoDiv.textContent = `Size: ${video.videoWidth}×${video.videoHeight}px | Duration: ${formatTime(video.duration)} | File size: ${formatFileSize(file.size)}`;570                preview.appendChild(infoDiv);571              };572            } 573            // Handle document files (PDF, PPTX, XLSX, TXT)574            else if (575              fileType === "application/pdf" || 576              fileExtension === "pdf" ||577              fileExtension === "txt" || 578              fileType === "text/plain" ||579              fileExtension === "pptx" || 580              fileType === "application/vnd.openxmlformats-officedocument.presentationml.presentation" ||581              fileExtension === "xlsx" || 582              fileType === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"583            ) {584              const fileIcon = document.createElement("div");585              fileIcon.style.fontSize = "3rem";586              fileIcon.style.marginBottom = "1rem";587              588              // Set appropriate icon based on file type589              if (fileType === "application/pdf" || fileExtension === "pdf") {590                fileIcon.textContent = "📄";591                fileIcon.title = "PDF Document";592              } else if (fileExtension === "pptx" || fileType.includes("presentation")) {593                fileIcon.textContent = "📊";594                fileIcon.title = "PowerPoint Presentation";595              } else if (fileExtension === "xlsx" || fileType.includes("spreadsheet")) {596                fileIcon.textContent = "📈";597                fileIcon.title = "Excel Spreadsheet";598              } else if (fileExtension === "txt" || fileType === "text/plain") {599                fileIcon.textContent = "📝";600                fileIcon.title = "Text File";601                602                // For text files, show a preview of the content603                const textPreview = document.createElement("pre");604                textPreview.style.maxHeight = "200px";605                textPreview.style.overflow = "auto";606                textPreview.style.backgroundColor = "#f5f5f5";607                textPreview.style.padding = "0.5rem";608                textPreview.style.borderRadius = "0.25rem";609                textPreview.style.fontSize = "0.875rem";610                textPreview.style.width = "100%";611                textPreview.style.whiteSpace = "pre-wrap";612                textPreview.style.wordBreak = "break-word";613                614                // Use FileReader to read text content615                const textReader = new FileReader();616                textReader.onload = function(e) {617                  // Limit text preview to first 1000 characters618                  const content = e.target.result.substring(0, 1000);619                  textPreview.textContent = content + (content.length < e.target.result.length ? "..." : "");620                };621                textReader.readAsText(file);622                623                preview.appendChild(textPreview);624              }625              626              preview.insertBefore(fileIcon, preview.firstChild);627              628              const docInfo = document.createElement("div");629              docInfo.className = "media-info";630              docInfo.textContent = `File: ${file.name} | Type: ${fileExtension.toUpperCase()} | Size: ${formatFileSize(file.size)}`;631              preview.appendChild(docInfo);632            } else {633              // Unsupported file type634              const unsupportedMsg = document.createElement("p");635              unsupportedMsg.textContent = "Unsupported file type";636              preview.appendChild(unsupportedMsg);637              638              const fileInfo = document.createElement("div");639              fileInfo.className = "media-info";640              fileInfo.textContent = `File: ${file.name} | Size: ${formatFileSize(file.size)}`;641              preview.appendChild(fileInfo);642            }643          };644          645          // Use appropriate reader method based on file type646          if (fileExtension === "txt" || fileType === "text/plain") {647            // Text files are handled within the above logic648            reader.readAsDataURL(file);649          } else {650            reader.readAsDataURL(file);651          }652        }653      }654 655      // Helper function to format file size656      function formatFileSize(bytes) {657        if (bytes < 1024) return bytes + " bytes";658        else if (bytes < 1048576) return (bytes / 1024).toFixed(1) + " KB";659        else return (bytes / 1048576).toFixed(1) + " MB";660      }661 662      // Helper function to format video duration663      function formatTime(seconds) {664        const min = Math.floor(seconds / 60);665        const sec = Math.floor(seconds % 60);666        return `${min}:${sec < 10 ? "0" + sec : sec}`;667      }668 669      // Add event listener for Enter key in the textarea670      document671        .getElementById("user-input")672        .addEventListener("keydown", function (event) {673          if (event.key === "Enter" && !event.shiftKey) {674            event.preventDefault();675            sendMessage();676          }677        });678    </script>679  </body>680</html>681