- Removed `SocialMediaService` and migrated core post generation logic to `GeneratePostService`. - Added `GetAllChatMessagesAction` for fetching chat history. - Introduced `MessageDto`, `MessageResource`, and `MessageCollection` for consistent backend API responses. - Updated frontend state and services to support JSON:API-compliant chat messages and history retrieval. - Improved typings and casting for chat message data.
64 lines
3.9 KiB
HTML
64 lines
3.9 KiB
HTML
<div class="max-w-[900px] mt-15 h-[80vh] mx-auto my-auto flex flex-col bg-white/5 backdrop-blur-[20px] border border-white/10 rounded-3xl shadow-[0_25px_50px_-12px_rgba(0,0,0,0.5),inset_0_1px_0_rgba(255,255,255,0.1)] overflow-hidden animate-[slideUpFade_0.8s_cubic-bezier(0.16,1,0.3,1)]">
|
|
<div class="px-8 py-6 border-b border-white/10 flex items-center gap-4 bg-black/20">
|
|
<div class="w-12 h-12 rounded-full bg-gradient-to-br from-[#00f2fe] to-[#4facfe] flex items-center justify-center font-semibold text-xl shadow-[0_0_20px_rgba(79,172,254,0.4)] animate-[pulse_2s_infinite]">AI</div>
|
|
<div>
|
|
<h1 class="m-0 text-xl font-semibold tracking-wide bg-gradient-to-r from-white to-indigo-300 bg-clip-text text-transparent">Post Assistant</h1>
|
|
<p class="m-0 mt-1 text-sm text-slate-400">Always online, ready to write.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex-1 overflow-y-auto p-8 flex flex-col gap-6 scroll-smooth custom-scrollbar" #scrollContainer>
|
|
@for (msg of chatStore.messages(); track msg.id) {
|
|
<div
|
|
class="flex flex-col max-w-[80%] animate-[messageAppear_0.5s_cubic-bezier(0.16,1,0.3,1)]"
|
|
[ngClass]="msg.attributes.role === 'user' ? 'self-end items-end' : 'self-start items-start'"
|
|
>
|
|
<div
|
|
class="px-5 py-4 rounded-2xl text-base leading-relaxed shadow-[0_4px_15px_rgba(0,0,0,0.1)] relative whitespace-pre-wrap"
|
|
[ngClass]="msg.attributes.role === 'user' ? 'bg-gradient-to-br from-indigo-500 to-purple-600 text-white rounded-br-sm' : 'bg-white/10 border border-white/5 text-slate-200 rounded-bl-sm backdrop-blur-md'"
|
|
>
|
|
{{ msg.attributes.content }}
|
|
</div>
|
|
<div class="text-xs text-slate-500 mt-2 px-1">
|
|
{{ msg.attributes.createdAt | date:'shortTime' }}
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
@if (chatStore.isLoading()) {
|
|
<div class="flex items-center gap-1.5 px-5 py-4 bg-white/5 rounded-2xl rounded-bl-sm self-start animate-[fadeIn_0.3s_ease-in-out]">
|
|
<div class="w-2 h-2 bg-[#4facfe] rounded-full animate-[typing_1.4s_infinite_ease-in-out_both] delay-[-0.32s]"></div>
|
|
<div class="w-2 h-2 bg-[#4facfe] rounded-full animate-[typing_1.4s_infinite_ease-in-out_both] delay-[-0.16s]"></div>
|
|
<div class="w-2 h-2 bg-[#4facfe] rounded-full animate-[typing_1.4s_infinite_ease-in-out_both] delay-0"></div>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
<div class="px-8 py-6 bg-black/30 border-t border-white/5">
|
|
@if (errorMessage) {
|
|
<div class="text-[#ff6b6b] text-sm mb-3 px-4 py-2 bg-[#ff6b6b]/10 rounded-lg border border-[#ff6b6b]/20 animate-[fadeIn_0.3s_ease-in-out]">
|
|
{{ errorMessage }}
|
|
</div>
|
|
}
|
|
<div class="flex gap-4 bg-white/5 px-4 py-2 rounded-full border border-white/10 transition-all duration-300 focus-within:bg-white/10 focus-within:border-[#4facfe]/50 focus-within:shadow-[0_0_20px_rgba(79,172,254,0.2)]">
|
|
<input
|
|
class="flex-1 bg-transparent border-none text-white text-base py-3 px-2 outline-none font-inherit placeholder-slate-500"
|
|
type="text"
|
|
[formControl]="messageControl"
|
|
(keydown.enter)="sendMessage()"
|
|
placeholder="Type a message..."
|
|
[disabled]="chatStore.isLoading()"
|
|
/>
|
|
<button
|
|
class="bg-gradient-to-br from-[#00f2fe] to-[#4facfe] border-none w-12 h-12 rounded-full flex items-center justify-center cursor-pointer text-white transition-all duration-200 hover:scale-105 hover:-translate-y-0.5 hover:shadow-[0_10px_20px_rgba(79,172,254,0.3)] active:scale-95 disabled:hover:scale-100 disabled:hover:translate-y-0 disabled:!bg-none disabled:bg-white/10 disabled:text-white/30 disabled:cursor-not-allowed disabled:transform-none disabled:shadow-none"
|
|
(click)="sendMessage()"
|
|
[disabled]="!messageControl.value || chatStore.isLoading()"
|
|
>
|
|
<svg class="w-5 h-5 fill-current" viewBox="0 0 24 24">
|
|
<path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|