MirrorDocs / index.html
humza7656's picture
Update index.html
a0494fe verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document Similarity Checker</title>
<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">
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
font-family: 'Inter', sans-serif;
background: linear-gradient(to bottom right, #141e30, #243b55);
}
.card {
backdrop-filter: blur(10px);
background-color: rgba(40, 50, 60, 0.7);
border: 1px solid rgba(255, 255, 255, 0.1);
transition: transform 0.3s ease-in-out, box-shadow 0.3s ease-in-out;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}
.file-input-wrapper {
transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out;
}
</style>
</head>
<body class="flex items-center justify-center min-h-screen p-4">
<!-- Main application container with a modern card design -->
<div class="card p-8 rounded-3xl shadow-2xl max-w-lg w-full text-center">
<h1 class="text-4xl font-bold text-white mb-2 tracking-wide">DocChecker</h1>
<p class="text-base text-gray-400 mb-8">Upload two .docx files to check their content similarity.</p>
<!-- Form for file uploads -->
<form id="uploadForm" class="space-y-6">
<div>
<label for="file1" class="block text-left text-sm font-medium text-gray-300 mb-1">Base Document</label>
<label for="file1" class="file-input-wrapper flex items-center justify-center space-x-2 cursor-pointer bg-gray-700 hover:bg-gray-600 rounded-lg p-4 transition duration-300 ease-in-out border-2 border-solid border-gray-600 focus-within:border-cyan-500">
<input type="file" id="file1" name="file1" accept=".docx" required class="hidden">
<!-- SVG icon for a document -->
<svg class="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 13h6m-3-3v6m5 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
</svg>
<span id="file1-name" class="text-sm font-medium text-gray-400">Choose a .docx file...</span>
</label>
</div>
<div>
<label for="file2" class="block text-left text-sm font-medium text-gray-300 mb-1">Candidate Document</label>
<label for="file2" class="file-input-wrapper flex items-center justify-center space-x-2 cursor-pointer bg-gray-700 hover:bg-gray-600 rounded-lg p-4 transition duration-300 ease-in-out border-2 border-solid border-gray-600 focus-within:border-cyan-500">
<input type="file" id="file2" name="file2" accept=".docx" required class="hidden">
<!-- SVG icon for a document -->
<svg class="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 13h6m-3-3v6m5 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
</svg>
<span id="file2-name" class="text-sm font-medium text-gray-400">Choose a .docx file...</span>
</label>
</div>
<!-- Submit button with a hover and active effect -->
<button type="submit" id="submitBtn" class="w-full py-3 px-4 bg-cyan-500 text-white font-semibold rounded-full
shadow-lg hover:bg-cyan-600 focus:outline-none focus:ring-2 focus:ring-cyan-500
focus:ring-offset-2 focus:ring-offset-gray-800 transition duration-300 ease-in-out
transform hover:scale-105 active:scale-95">
Check Similarity
</button>
</form>
<!-- Area for displaying results or messages -->
<div id="resultContainer" class="mt-8 relative min-h-[100px] flex items-center justify-center">
<!-- Loading spinner with animation -->
<div id="loading" class="hidden text-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 opacity-0 transition-opacity duration-500 ease-in-out">
<div class="inline-block h-10 w-10 animate-spin rounded-full border-4 border-solid border-current border-r-transparent text-cyan-400" role="status">
<span class="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]">Loading...</span>
</div>
<p class="mt-3 text-sm text-gray-400">Checking files...</p>
</div>
<!-- Result display area with fade-in effect -->
<div id="result" class="hidden absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 opacity-0 transition-opacity duration-500 ease-in-out">
<p class="text-xl text-gray-300">Similarity Score:</p>
<p id="score" class="text-6xl font-extrabold text-cyan-400 mt-2"></p>
</div>
<!-- Error message display area with fade-in effect -->
<div id="error" class="hidden absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 opacity-0 transition-opacity duration-500 ease-in-out">
<p id="errorMessage" class="text-red-400 text-sm font-medium mt-2"></p>
</div>
</div>
<!-- Developer Information Section -->
<div class="mt-12 pt-6 border-t border-gray-700 text-gray-400 text-sm">
<p class="mb-2">Developed by Muhammad Hamza</p>
<div class="flex justify-center space-x-6">
<a href="https://github.com/MuhammadHamza123c" target="_blank" class="hover:text-white transition duration-200" title="GitHub">
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.956 0-1.091.39-1.984 1.029-2.682-.103-.253-.446-1.272.098-2.651 0 0 .84-.268 2.75 1.022A9.615 9.615 0 0112 6.865c.85.006 1.704.114 2.504.337 1.909-1.29 2.747-1.022 2.747-1.022.546 1.379.202 2.398.099 2.651.64.698 1.028 1.591 1.028 2.682 0 3.854-2.339 4.691-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd" />
</svg>
</a>
<a href="https://www.linkedin.com/in/muhammad-hamzads/" target="_blank" class="hover:text-white transition duration-200" title="LinkedIn">
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/>
</svg>
</a>
<a href="mailto:muhammadhamzao241@gmaul.com" target="_blank" class="hover:text-white transition duration-200" title="Email">
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 12.713l-11.985-9.713h23.97l-11.985 9.713zm0 2.574l-12-9.722v16.435h24v-16.435l-12 9.722z"/>
</svg>
</a>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('uploadForm');
const file1Input = document.getElementById('file1');
const file2Input = document.getElementById('file2');
const submitBtn = document.getElementById('submitBtn');
const loading = document.getElementById('loading');
const resultDiv = document.getElementById('result');
const scoreSpan = document.getElementById('score');
const errorDiv = document.getElementById('error');
const errorMessageSpan = document.getElementById('errorMessage');
// The base URL for the FastAPI service
const baseUrl = 'https://humza7656-my-doc-checker.hf.space';
// Function to show a message box by fading in the content
function showMessage(element, message, isError = false) {
// Hide all result containers first
loading.classList.add('hidden', 'opacity-0');
resultDiv.classList.add('hidden', 'opacity-0');
errorDiv.classList.add('hidden', 'opacity-0');
if (isError) {
errorMessageSpan.textContent = message;
} else {
scoreSpan.textContent = message;
}
// Show the specific element and fade it in
element.classList.remove('hidden');
setTimeout(() => element.classList.remove('opacity-0'), 10);
}
// Update the display text for file inputs
file1Input.addEventListener('change', (event) => {
const fileName = event.target.files[0] ? event.target.files[0].name : 'Choose a .docx file...';
document.getElementById('file1-name').textContent = fileName;
});
file2Input.addEventListener('change', (event) => {
const fileName = event.target.files[0] ? event.target.files[0].name : 'Choose a .docx file...';
document.getElementById('file2-name').textContent = fileName;
});
form.addEventListener('submit', async (e) => {
e.preventDefault();
// Get the files from the input fields
const file1 = file1Input.files[0];
const file2 = file2Input.files[0];
// Simple client-side validation for file types
if (!file1 || !file2) {
showMessage(errorDiv, 'Please select both files.', true);
return;
}
if (!file1.name.endsWith('.docx') || !file2.name.endsWith('.docx')) {
showMessage(errorDiv, 'Both files must be of type .docx', true);
return;
}
// Show loading state
showMessage(loading, '', false);
submitBtn.disabled = true;
// Create a FormData object to send the files
const formData = new FormData();
formData.append('f1', file1);
formData.append('f2', file2);
try {
const response = await fetch(`${baseUrl}/similar_doc`, {
method: 'POST',
body: formData
});
const data = await response.json();
if (response.ok) {
// API call was successful
const similarity = data.Similarity;
showMessage(resultDiv, similarity.toFixed(2));
} else {
// API returned an error
const errorMsg = data.error || 'An unknown error occurred.';
showMessage(errorDiv, errorMsg, true);
}
} catch (error) {
// Network or other fetch-related error
console.error('Error:', error);
showMessage(errorDiv, 'Could not connect to the API. Please try again later.', true);
} finally {
// Re-enable button
submitBtn.disabled = false;
}
});
});
</script>
</body>
</html>