|
@@ -0,0 +1,172 @@
|
|
|
+<template>
|
|
|
+ <div class="chat-container flex flex-col h-screen">
|
|
|
+ <header class="bg-gray-800 text-white px-4 py-2 flex items-center justify-between">
|
|
|
+ <div class="flex items-center">
|
|
|
+ <LucideUserCircle class="w-10 h-10 mr-2" />
|
|
|
+ <div>
|
|
|
+ <h2 class="text-lg font-bold">Chat with John Doe</h2>
|
|
|
+ <p class="text-sm">Online</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <button class="bg-blue-500 text-white px-3 py-1 rounded">Options</button>
|
|
|
+ </header>
|
|
|
+ <main class="flex-1 p-4 overflow-y-auto">
|
|
|
+ <div v-for="(message, index) in messages" :key="index" class="message mb-2">
|
|
|
+ <div v-if="message.sender === 'user'" class="self-end bg-blue-100 p-2 rounded-tl-lg rounded-bl-lg rounded-br-lg">
|
|
|
+ <p>{{ message.text }}</p>
|
|
|
+ <p class="text-xs text-gray-500">{{ message.time }}</p>
|
|
|
+ </div>
|
|
|
+ <div v-else class="self-start bg-gray-100 p-2 rounded-tr-lg rounded-bl-lg rounded-br-lg">
|
|
|
+ <p>{{ message.text }}</p>
|
|
|
+ <p class="text-xs text-gray-500">{{ message.time }}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </main>
|
|
|
+ <footer class="bg-gray-800 p-4 flex items-center">
|
|
|
+ <div class="footer-icons">
|
|
|
+ <button @click="showEmojis = !showEmojis" class="bg-gray-700 text-white px-3 py-2 rounded-l-lg"><LucideSmile /></button>
|
|
|
+ <button @click="$refs.fileInput.click()" class="bg-gray-700 text-white px-3 py-2 rounded-r-lg"><LucidePaperclip /></button>
|
|
|
+ <input type="file" ref="fileInput" @change="handleFileUpload" class="hidden" />
|
|
|
+ </div>
|
|
|
+ <input v-model="newMessage" @keyup.enter="sendMessage" class="flex-1 bg-gray-700 text-white p-2 rounded-l-lg focus:outline-none" placeholder="Type a message" />
|
|
|
+ <button @click="sendMessage" class="bg-blue-500 text-white px-3 py-2 rounded-r-lg">Send</button>
|
|
|
+ </footer>
|
|
|
+ <div v-if="showEmojis" class="emoji-list">
|
|
|
+ <button v-for="emoji in emojiList" :key="emoji" @click="addEmoji(emoji)">{{ emoji }}</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { ref, onMounted, watch } from 'vue';
|
|
|
+import { useRouter } from 'vue-router';
|
|
|
+import { LucideUserCircle, LucideSend, LucideSmile, LucidePaperclip } from 'lucide-vue-next';
|
|
|
+
|
|
|
+export default {
|
|
|
+ components: {
|
|
|
+ LucideUserCircle,
|
|
|
+ LucideSend,
|
|
|
+ LucideSmile,
|
|
|
+ LucidePaperclip
|
|
|
+ },
|
|
|
+ setup() {
|
|
|
+ const router = useRouter();
|
|
|
+ const messages = ref([]);
|
|
|
+ const newMessage = ref('');
|
|
|
+ const showEmojis = ref(false);
|
|
|
+ const emojiList = ['😊', '😢', '😄', '🤔', '👍', '👎'];
|
|
|
+ const selectedEmoji = ref('');
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ const storedMessages = localStorage.getItem('chatMessages');
|
|
|
+ if (storedMessages) {
|
|
|
+ messages.value = JSON.parse(storedMessages);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ watch(messages, (newMessages) => {
|
|
|
+ localStorage.setItem('chatMessages', JSON.stringify(newMessages));
|
|
|
+ }, { deep: true });
|
|
|
+
|
|
|
+ const sendMessage = () => {
|
|
|
+ if (newMessage.value.trim() || selectedEmoji.value) {
|
|
|
+ messages.value.push({ sender: 'user', text: newMessage.value + selectedEmoji.value, time: new Date().toLocaleTimeString() });
|
|
|
+ newMessage.value = '';
|
|
|
+ selectedEmoji.value = '';
|
|
|
+ // Scroll to bottom
|
|
|
+ setTimeout(() => {
|
|
|
+ const container = document.querySelector('.chat-container main');
|
|
|
+ container.scrollTop = container.scrollHeight;
|
|
|
+ }, 0);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const addEmoji = (emoji) => {
|
|
|
+ selectedEmoji.value = emoji;
|
|
|
+ sendMessage();
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleFileUpload = (event) => {
|
|
|
+ const file = event.target.files[0];
|
|
|
+ if (file) {
|
|
|
+ const reader = new FileReader();
|
|
|
+ reader.onload = (e) => {
|
|
|
+ messages.value.push({ sender: 'user', text: `Attachment: ${file.name}`, time: new Date().toLocaleTimeString(), attachment: e.target.result });
|
|
|
+ // Scroll to bottom
|
|
|
+ setTimeout(() => {
|
|
|
+ const container = document.querySelector('.chat-container main');
|
|
|
+ container.scrollTop = container.scrollHeight;
|
|
|
+ }, 0);
|
|
|
+ };
|
|
|
+ reader.readAsDataURL(file);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ return {
|
|
|
+ messages,
|
|
|
+ newMessage,
|
|
|
+ sendMessage,
|
|
|
+ showEmojis,
|
|
|
+ emojiList,
|
|
|
+ addEmoji,
|
|
|
+ handleFileUpload,
|
|
|
+ router
|
|
|
+ };
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.chat-container {
|
|
|
+ background-color: #1f2937;
|
|
|
+ color: white;
|
|
|
+}
|
|
|
+
|
|
|
+.message {
|
|
|
+ max-width: 75%;
|
|
|
+}
|
|
|
+
|
|
|
+.message .text {
|
|
|
+ word-wrap: break-word;
|
|
|
+}
|
|
|
+
|
|
|
+footer input {
|
|
|
+ border-right: none;
|
|
|
+}
|
|
|
+
|
|
|
+footer button {
|
|
|
+ border-left: none;
|
|
|
+}
|
|
|
+
|
|
|
+.footer-icons {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.footer-icons button {
|
|
|
+ margin-right: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.emoji-list {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 48px;
|
|
|
+ left: 0;
|
|
|
+ background-color: #1f2937;
|
|
|
+ padding: 8px;
|
|
|
+ border-radius: 8px;
|
|
|
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
|
+}
|
|
|
+
|
|
|
+.emoji-list button {
|
|
|
+ background: none;
|
|
|
+ border: none;
|
|
|
+ color: white;
|
|
|
+ cursor: pointer;
|
|
|
+ padding: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.emoji-list button:hover {
|
|
|
+ background-color: #334155;
|
|
|
+ border-radius: 4px;
|
|
|
+}
|
|
|
+</style>
|