mostasharak / okod.html
joermd's picture
Update okod.html
4fdcf0f verified
raw
history blame
22.6 kB
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>منشئ العقود الذكي</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" rel="stylesheet">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans+Arabic:wght@300;400;500;600;700&display=swap');
body {
font-family: 'IBM Plex Sans Arabic', sans-serif;
background: #ffffff;
min-height: 100vh;
}
.split-screen {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
max-width: 1400px;
margin: 2rem auto;
padding: 0 2rem;
min-height: calc(100vh - 4rem);
}
.input-group {
position: relative;
margin-bottom: 1.5rem;
}
.input-group input, .input-group textarea, .input-group select {
width: 100%;
padding: 1rem 1.25rem;
border: 2px solid #e5e7eb;
border-radius: 1rem;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
background: #ffffff;
font-size: 1rem;
}
.input-group input:focus, .input-group textarea:focus, .input-group select:focus {
border-color: #2563eb;
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.1);
outline: none;
transform: translateY(-2px);
}
.card {
background: white;
border-radius: 1.5rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
padding: 2.5rem;
height: fit-content;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
border: 1px solid #f3f4f6;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.12);
}
.contract-output {
background: #fafafa;
border-radius: 1rem;
padding: 2rem;
min-height: 300px;
line-height: 1.8;
font-size: 1.1rem;
border: 1px solid #f3f4f6;
}
.btn {
background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
color: white;
padding: 1rem 2.5rem;
border-radius: 1rem;
font-weight: 600;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
border: none;
cursor: pointer;
font-size: 1.1rem;
position: relative;
overflow: hidden;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(37, 99, 235, 0.25);
}
.btn:active {
transform: translateY(0);
}
.copy-btn {
position: absolute;
top: 1rem;
left: 1rem;
padding: 0.5rem 1rem;
background: #f3f4f6;
border-radius: 0.75rem;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.9rem;
color: #4b5563;
}
.copy-btn:hover {
background: #e5e7eb;
}
.success-message {
position: fixed;
bottom: 2rem;
right: 2rem;
background: #10b981;
color: white;
padding: 1rem 2rem;
border-radius: 1rem;
animation: slideIn 0.3s ease;
}
@keyframes slideIn {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
.loading {
position: relative;
}
.loading::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);
animation: loading 1.5s infinite;
}
.section-title {
font-size: 1.25rem;
color: #1f2937;
margin-bottom: 1.5rem;
padding-bottom: 0.75rem;
border-bottom: 2px solid #e5e7eb;
font-weight: 600;
}
.contract-type-selector {
display: flex;
gap: 1rem;
margin-bottom: 2rem;
}
.type-option {
flex: 1;
padding: 1.5rem;
border: 2px solid #e5e7eb;
border-radius: 1rem;
cursor: pointer;
transition: all 0.3s ease;
text-align: center;
}
.type-option.active {
border-color: #2563eb;
background: rgba(37, 99, 235, 0.05);
}
.type-option:hover {
transform: translateY(-2px);
}
@media (max-width: 768px) {
.split-screen {
grid-template-columns: 1fr;
padding: 1rem;
}
.card {
margin-bottom: 1rem;
padding: 1.5rem;
}
}
</style>
</head>
<body>
<div class="split-screen">
<div class="card animate__animated animate__fadeInRight">
<h1 class="text-4xl font-bold mb-8 text-center text-gray-800">منشئ العقود الذكي</h1>
<div class="contract-type-selector">
<div class="type-option active" data-type="rental">
<h3 class="font-bold mb-2">عقد إيجار</h3>
<p class="text-sm text-gray-600">عقود الإيجار السكنية والتجارية</p>
</div>
<div class="type-option" data-type="custom">
<h3 class="font-bold mb-2">عقد مخصص</h3>
<p class="text-sm text-gray-600">صياغة عقد حسب احتياجاتك</p>
</div>
</div>
<div id="rentalTemplate" class="contract-template active space-y-6">
<h2 class="section-title">معلومات العقد الأساسية</h2>
<div class="input-group">
<label class="block text-gray-700 font-bold mb-2">المؤجر:</label>
<input type="text" id="landlord" placeholder="اسم المؤجر الكامل" class="focus:ring-2 focus:ring-blue-500">
</div>
<div class="input-group">
<label class="block text-gray-700 font-bold mb-2">المستأجر:</label>
<input type="text" id="tenant" placeholder="اسم المستأجر الكامل">
</div>
<h2 class="section-title">تفاصيل العقار والإيجار</h2>
<div class="input-group">
<label class="block text-gray-700 font-bold mb-2">عنوان العقار:</label>
<input type="text" id="propertyAddress" placeholder="العنوان التفصيلي للعقار">
</div>
<div class="grid grid-cols-2 gap-4">
<div class="input-group">
<label class="block text-gray-700 font-bold mb-2">مدة الإيجار:</label>
<input type="text" id="rentalPeriod" placeholder="مثال: سنة واحدة">
</div>
<div class="input-group">
<label class="block text-gray-700 font-bold mb-2">قيمة الإيجار:</label>
<input type="text" id="rentalAmount" placeholder="القيمة بالجنيه المصري">
</div>
</div>
<div class="input-group">
<label class="block text-gray-700 font-bold mb-2">شروط إضافية:</label>
<textarea id="additionalTerms" class="h-32" placeholder="أي شروط أو ملاحظات إضافية"></textarea>
</div>
</div>
<div id="customTemplate" class="contract-template hidden space-y-6">
<h2 class="section-title">معلومات العقد المخصص</h2>
<div class="input-group">
<label class="block text-gray-700 font-bold mb-2">عنوان العقد:</label>
<input type="text" id="contractTitle" placeholder="عنوان العقد">
</div>
<div class="input-group">
<label class="block text-gray-700 font-bold mb-2">الطرف الأول:</label>
<input type="text" id="firstParty" placeholder="اسم الطرف الأول">
</div>
<div class="input-group">
<label class="block text-gray-700 font-bold mb-2">الطرف الثاني:</label>
<input type="text" id="secondParty" placeholder="اسم الطرف الثاني">
</div>
<div class="input-group">
<label class="block text-gray-700 font-bold mb-2">تفاصيل العقد:</label>
<textarea id="contractDetails" class="h-64" placeholder="اكتب تفاصيل العقد هنا"></textarea>
</div>
</div>
<div class="mt-8 flex justify-center">
<button id="generateButton" class="btn">
إنشاء العقد
</button>
</div>
</div>
<div class="card animate__animated animate__fadeInLeft">
<h2 class="text-2xl font-bold mb-6 text-gray-800">العقد المنشأ</h2>
<div class="relative">
<button class="copy-btn" id="copyButton">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
</svg>
نسخ العقد
</button>
<div id="contractOutput" class="contract-output prose"></div>
</div>
</div>
</div>
<script>
const API_URL = 'https://j8fp9mu44k547j-7777.proxy.runpod.net/proxy/8000/chat';
let currentController = null;
// تحسين تجربة المستخدم للمدخلات
document.querySelectorAll('input, textarea').forEach(element => {
element.addEventListener('focus', function() {
this.closest('.input-group').classList.add('focused');
this.style.transform = 'translateY(-2px)';
});
element.addEventListener('blur', function() {
this.closest('.input-group').classList.remove('focused');
this.style.transform = 'translateY(0)';
});
// إضافة تأثير ripple عند النقر
element.addEventListener('click', function(e) {
const ripple = document.createElement('div');
ripple.classList.add('ripple');
this.appendChild(ripple);
setTimeout(() => ripple.remove(), 1000);
});
});
// تحسين تبديل نوع العقد
document.querySelectorAll('.type-option').forEach(option => {
option.addEventListener('click', function() {
// إزالة الفئة النشطة من جميع الخيارات
document.querySelectorAll('.type-option').forEach(opt => {
opt.classList.remove('active');
});
// إضافة الفئة النشطة للخيار المحدد
this.classList.add('active');
// إخفاء جميع النماذج
document.querySelectorAll('.contract-template').forEach(template => {
template.classList.add('hidden');
});
// إظهار النموذج المحدد
const templateId = this.dataset.type === 'rental' ? 'rentalTemplate' : 'customTemplate';
// إظهار النموذج المحدد مع تأثير حركي
const selectedTemplate = document.getElementById(templateId);
selectedTemplate.classList.remove('hidden');
selectedTemplate.classList.add('animate__animated', 'animate__fadeIn');
});
});
// نسخ العقد إلى الحافظة
document.getElementById('copyButton').addEventListener('click', async function() {
const contractText = document.getElementById('contractOutput').innerText;
try {
await navigator.clipboard.writeText(contractText);
// إظهار رسالة نجاح
const successMessage = document.createElement('div');
successMessage.className = 'success-message animate__animated animate__fadeIn';
successMessage.textContent = 'تم نسخ العقد بنجاح!';
document.body.appendChild(successMessage);
// إزالة رسالة النجاح بعد ثانيتين
setTimeout(() => {
successMessage.classList.add('animate__fadeOut');
setTimeout(() => successMessage.remove(), 300);
}, 2000);
} catch (err) {
console.error('فشل نسخ النص: ', err);
}
});
// تحسين عملية إنشاء العقد
document.getElementById('generateButton').addEventListener('click', async function() {
const button = this;
const outputDiv = document.getElementById('contractOutput');
const contractType = document.querySelector('.type-option.active').dataset.type;
let prompt = '';
// تجميع البيانات حسب نوع العقد
if (contractType === 'rental') {
const formData = {
landlord: document.getElementById('landlord').value,
tenant: document.getElementById('tenant').value,
propertyAddress: document.getElementById('propertyAddress').value,
rentalPeriod: document.getElementById('rentalPeriod').value,
rentalAmount: document.getElementById('rentalAmount').value,
additionalTerms: document.getElementById('additionalTerms').value
};
// التحقق من البيانات المطلوبة
const requiredFields = ['landlord', 'tenant', 'propertyAddress', 'rentalPeriod', 'rentalAmount'];
const missingFields = requiredFields.filter(field => !formData[field]);
if (missingFields.length > 0) {
outputDiv.innerHTML = `
<div class="text-red-500 font-bold mb-4">يرجى ملء الحقول التالية:</div>
<ul class="list-disc list-inside text-red-500">
${missingFields.map(field => `<li>${getFieldLabel(field)}</li>`).join('')}
</ul>
`;
return;
}
prompt = `أنشئ عقد إيجار رسمي باللغة العربية يتضمن البيانات التالية:
المؤجر: ${formData.landlord}
المستأجر: ${formData.tenant}
عنوان العقار: ${formData.propertyAddress}
مدة الإيجار: ${formData.rentalPeriod}
قيمة الإيجار: ${formData.rentalAmount}
${formData.additionalTerms ? `شروط إضافية: ${formData.additionalTerms}` : ''}
يجب أن يكون العقد شاملاً وقانونياً ويحتوي على كافة البنود الأساسية المتعارف عليها في عقود الإيجار.`;
} else {
const formData = {
title: document.getElementById('contractTitle').value,
firstParty: document.getElementById('firstParty').value,
secondParty: document.getElementById('secondParty').value,
details: document.getElementById('contractDetails').value
};
// التحقق من البيانات المطلوبة
const requiredFields = ['title', 'firstParty', 'secondParty', 'details'];
const missingFields = requiredFields.filter(field => !formData[field]);
if (missingFields.length > 0) {
outputDiv.innerHTML = `
<div class="text-red-500 font-bold mb-4">يرجى ملء الحقول التالية:</div>
<ul class="list-disc list-inside text-red-500">
${missingFields.map(field => `<li>${getFieldLabel(field)}</li>`).join('')}
</ul>
`;
return;
}
prompt = `أنشئ عقداً مخصصاً باللغة العربية يتضمن البيانات التالية:
عنوان العقد: ${formData.title}
الطرف الأول: ${formData.firstParty}
الطرف الثاني: ${formData.secondParty}
تفاصيل العقد: ${formData.details}
يجب أن يكون العقد رسمياً وقانونياً ومنظماً بشكل احترافي.`;
}
if (currentController) {
currentController.abort();
currentController = null;
button.textContent = 'إنشاء العقد';
button.classList.remove('loading');
return;
}
try {
// تحديث واجهة المستخدم لحالة التحميل
button.textContent = 'إيقاف الإنشاء';
button.classList.add('loading');
outputDiv.innerHTML = `
<div class="flex items-center justify-center space-x-4 text-gray-600">
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
<span>جاري إنشاء العقد...</span>
</div>
`;
currentController = new AbortController();
const response = await fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
message: prompt,
history: []
}),
signal: currentController.signal
});
const data = await response.json();
outputDiv.innerHTML = data.response.replace(/\n/g, '<br>');
outputDiv.classList.add('animate__animated', 'animate__fadeIn');
} catch (error) {
if (error.name === 'AbortError') {
outputDiv.innerHTML = `
<div class="text-yellow-600 font-bold">
تم إيقاف إنشاء العقد
</div>
`;
} else {
outputDiv.innerHTML = `
<div class="text-red-600 font-bold">
عذراً، حدث خطأ في إنشاء العقد. يرجى المحاولة مرة أخرى.
</div>
`;
}
} finally {
currentController = null;
button.textContent = 'إنشاء العقد';
button.classList.remove('loading');
}
});
// دالة مساعدة للحصول على تسميات الحقول بالعربية
function getFieldLabel(field) {
const labels = {
landlord: 'المؤجر',
tenant: 'المستأجر',
propertyAddress: 'عنوان العقار',
rentalPeriod: 'مدة الإيجار',
rentalAmount: 'قيمة الإيجار',
title: 'عنوان العقد',
firstParty: 'الطرف الأول',
secondParty: 'الطرف الثاني',
details: 'تفاصيل العقد'
};
return labels[field] || field;
}
// إضافة تأثيرات حركية عند التمرير
const cards = document.querySelectorAll('.card');
window.addEventListener('scroll', () => {
cards.forEach(card => {
const rect = card.getBoundingClientRect();
const isVisible = rect.top < window.innerHeight && rect.bottom >= 0;
if (isVisible) {
card.style.transform = 'translateY(-4px)';
} else {
card.style.transform = 'translateY(0)';
}
});
});
</script>
</body>
</html>