First Commit
This commit is contained in:
Executable
+146
@@ -0,0 +1,146 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', __('Chat with AI'))
|
||||
|
||||
@section('header')
|
||||
<div class="flex justify-between items-center">
|
||||
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
|
||||
{{ __('Chat with AI') }}
|
||||
</h2>
|
||||
<div class="flex items-center gap-4">
|
||||
<x-language-selector variant="text-gray-600 hover:text-gray-800" />
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="py-6">
|
||||
<div class="max-w-4xl mx-auto sm:px-6 lg:px-8">
|
||||
@if(session('success'))
|
||||
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded-lg mb-6">
|
||||
{{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if(session('error'))
|
||||
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-lg mb-6">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Chat Container -->
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 flex flex-col" style="height: calc(100vh - 250px); min-height: 500px;">
|
||||
<!-- Chat Header -->
|
||||
<div class="p-4 border-b border-gray-100 flex justify-between items-center">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-gray-900">{{ __('Chat with AI') }}</h3>
|
||||
<p class="text-sm text-gray-500">{{ __('Ask anything to the AI models') }}</p>
|
||||
</div>
|
||||
<form action="{{ route('chat.destroy') }}" method="POST" onsubmit="return confirm('{{ __("Clear chat history?") }}')">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="text-sm text-red-600 hover:text-red-800">
|
||||
{{ __('Clear History') }}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Warning Banner -->
|
||||
<div class="bg-yellow-50 border-l-4 border-yellow-400 p-4">
|
||||
<div class="flex">
|
||||
<div class="flex-shrink-0">
|
||||
<svg class="h-5 w-5 text-yellow-400" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<p class="text-sm text-yellow-700">
|
||||
{{ __('Do not share sensitive personal data, use profanity, or discuss prohibited topics such as pornography, politics, religion, or prejudice. Violations may result in account restrictions.') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Chat Messages -->
|
||||
<div id="chatMessages" class="flex-1 overflow-y-auto p-4 space-y-4">
|
||||
@forelse($chatHistory as $chat)
|
||||
<div class="flex flex-col space-y-2">
|
||||
<!-- User Message -->
|
||||
<div class="flex justify-end">
|
||||
<div class="bg-indigo-600 text-white rounded-lg px-4 py-2 max-w-[80%]">
|
||||
<p class="text-sm whitespace-pre-wrap">{{ $chat->message }}</p>
|
||||
<p class="text-xs text-indigo-200 mt-1">{{ $chat->created_at->format('H:i') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- AI Response -->
|
||||
@if($chat->response)
|
||||
<div class="flex justify-start">
|
||||
<div class="bg-gray-100 text-gray-800 rounded-lg px-4 py-2 max-w-[80%]">
|
||||
<div class="text-sm prose prose-sm max-w-none">
|
||||
{!! \App\Services\MarkdownService::parse($chat->response) !!}
|
||||
</div>
|
||||
<div class="flex items-center gap-2 mt-1">
|
||||
<p class="text-xs text-gray-400">{{ $chat->created_at->format('H:i') }}</p>
|
||||
<span class="text-xs text-gray-400">|</span>
|
||||
<span class="text-xs text-gray-400">{{ ucfirst($chat->provider) }}</span>
|
||||
<span class="text-xs text-gray-400">|</span>
|
||||
<span class="text-xs text-gray-400">{{ $chat->model }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@empty
|
||||
<div class="flex items-center justify-center h-full">
|
||||
<div class="text-center">
|
||||
<svg class="w-16 h-16 text-gray-300 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"/>
|
||||
</svg>
|
||||
<p class="text-gray-500 text-lg">{{ __('Start a conversation with AI!') }}</p>
|
||||
<p class="text-gray-400 text-sm mt-2">{{ __('Type a message below to begin.') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
<!-- Chat Input -->
|
||||
<div class="p-4 border-t border-gray-100">
|
||||
<form action="{{ route('chat.store') }}" method="POST" class="flex gap-2">
|
||||
@csrf
|
||||
<div class="flex-1 flex gap-2">
|
||||
<input type="text"
|
||||
name="message"
|
||||
placeholder="{{ __('Type your message...') }}"
|
||||
class="flex-1 text-sm border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500"
|
||||
autocomplete="off"
|
||||
required>
|
||||
<button type="submit" class="bg-indigo-600 text-white px-6 py-2 rounded-lg hover:bg-indigo-700 transition">
|
||||
{{ __('Send') }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
// Auto-scroll to bottom of chat
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const chatMessages = document.getElementById('chatMessages');
|
||||
if (chatMessages) {
|
||||
chatMessages.scrollTop = chatMessages.scrollHeight;
|
||||
}
|
||||
});
|
||||
|
||||
// Focus input on load
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const input = document.querySelector('input[name="message"]');
|
||||
if (input) {
|
||||
input.focus();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
Reference in New Issue
Block a user