From 34ab6fb2196220e8bb01fbad3082b1adaabf6069 Mon Sep 17 00:00:00 2001 From: Hitesh Date: Mon, 26 May 2025 20:51:36 +0530 Subject: [PATCH 1/2] First commit for instagram stories project --- README.md | 25 ++- package-lock.json | 4 +- package.json | 2 +- src/App.css | 349 +-------------------------------- src/App.jsx | 117 +---------- src/components/Stories.jsx | 54 +++++ src/components/StoriesList.jsx | 24 +++ src/components/StoryView.jsx | 106 ++++++++++ src/data/stories.json | 32 +++ src/styles/Stories.css | 12 ++ src/styles/StoriesList.css | 36 ++++ src/styles/StoryView.css | 98 +++++++++ 12 files changed, 387 insertions(+), 472 deletions(-) create mode 100644 src/components/Stories.jsx create mode 100644 src/components/StoriesList.jsx create mode 100644 src/components/StoryView.jsx create mode 100644 src/data/stories.json create mode 100644 src/styles/Stories.css create mode 100644 src/styles/StoriesList.css create mode 100644 src/styles/StoryView.css diff --git a/README.md b/README.md index 334c116..7059a96 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,12 @@ -These are the sequence of commands to run this chat application on any laptop:- - -1. mkdir chat-project -2. cd chat-project -3. Initialize a new Vite React project:- npm create vite@latest -4. Install the required dependencies:- npm install -5. Replace the default files with our chat application code: - a. Create the component files in the src/components directory - b. Update App.jsx, App.css, and other files as we have in this code. -6. Start the development server:- npm run dev -7. Open the application in your browser:- - a. The terminal will show a URL (usually http://localhost:5173/) - b. Open this URL in your browser +# React + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project. diff --git a/package-lock.json b/package-lock.json index 19e24d3..28967fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "chat-project", + "name": "instagram-stories-project", "version": "0.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "chat-project", + "name": "instagram-stories-project", "version": "0.0.0", "dependencies": { "react": "^19.1.0", diff --git a/package.json b/package.json index 726a895..48bf766 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "chat-project", + "name": "instagram-stories-project", "private": true, "version": "0.0.0", "type": "module", diff --git a/src/App.css b/src/App.css index 4816779..6ade16d 100644 --- a/src/App.css +++ b/src/App.css @@ -1,349 +1,14 @@ -#root { - max-width: 100%; - margin: 0; - padding: 0; - text-align: left; - height: 100vh; -} - -.chat-app { - display: flex; - height: 100vh; - width: 100%; - overflow: hidden; -} - -.sidebar { - width: 280px; - background-color: #f5f5f5; - border-right: 1px solid #e0e0e0; - display: flex; - flex-direction: column; -} - -.new-chat { - padding: 15px; - border-bottom: 1px solid #e0e0e0; -} - -.new-chat-btn { - width: 100%; - padding: 10px; - background-color: #0078d4; - color: white; - border: none; - border-radius: 4px; - cursor: pointer; -} - -.new-chat form { - display: flex; - flex-direction: column; - gap: 10px; -} - -.new-chat input { - padding: 8px; - border: 1px solid #ccc; - border-radius: 4px; -} - -.new-chat .buttons { - display: flex; - gap: 10px; -} - -.new-chat .cancel { - background-color: #f0f0f0; - color: #333; -} - -.chat-list { - flex: 1; - overflow-y: auto; -} - -.chat-list h2 { - padding: 0 15px; - font-size: 16px; - color: #666; -} - -.chat-list ul { - list-style: none; - padding: 0; - margin: 0; -} - -.chat-list li { - padding: 12px 15px; - cursor: pointer; - display: flex; - justify-content: space-between; - align-items: center; - border-bottom: 1px solid #eee; -} - -.chat-list li:hover { - background-color: #eaeaea; -} - -.chat-list li.active { - background-color: #e1effa; - border-left: 3px solid #0078d4; -} - -.delete-btn { - background: none; - border: none; - color: #999; - font-size: 18px; - cursor: pointer; -} - -.delete-btn:hover { - color: #d32f2f; -} - -.chat-window { - flex: 1; - display: flex; - flex-direction: column; - background-color: #fff; -} - -.chat-header { - padding: 15px; - border-bottom: 1px solid #e0e0e0; - background-color: #f9f9f9; -} - -.chat-header h2 { - margin: 0; - font-size: 18px; -} - -.message-list { - flex: 1; - overflow-y: auto; - padding: 15px; - display: flex; - flex-direction: column; - gap: 10px; - background-color: #f5f5f5; -} - -.empty-message { - text-align: center; - color: #999; - margin-top: 40px; -} - -.message { - max-width: 70%; - margin-bottom: 10px; -} - -.message.sent { - align-self: flex-end; -} - -.message.received { - align-self: flex-start; -} - -.message-content { - padding: 10px 15px; - border-radius: 18px; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); -} - -.message.sent .message-content { - background-color: #0078d4; - color: white; - border-bottom-right-radius: 4px; -} - -.message.received .message-content { - background-color: white; - border-bottom-left-radius: 4px; -} - -.message-header { - display: flex; - justify-content: space-between; - margin-bottom: 5px; - font-size: 12px; -} - -.message p { +* { margin: 0; - word-break: break-word; -} - -.message-input { - display: flex; - padding: 15px; - border-top: 1px solid #e0e0e0; - background-color: #f9f9f9; -} - -.message-input input { - flex: 1; - padding: 10px 15px; - border: 1px solid #ccc; - border-radius: 20px; - margin-right: 10px; - font-size: 14px; -} - -.message-input button { - padding: 10px 20px; - background-color: #0078d4; - color: white; - border: none; - border-radius: 20px; - cursor: pointer; -} - -.chat-info { - display: flex; - align-items: center; - gap: 8px; - flex: 1; -} - -.chat-icon { - width: 20px; - text-align: center; -} - -.member-count { - background-color: #e0e0e0; - border-radius: 10px; - padding: 2px 6px; - font-size: 12px; - color: #666; -} - -.chat-header-info { - display: flex; - justify-content: space-between; - align-items: center; -} - -.members-toggle { - background-color: #f0f0f0; - border: 1px solid #ddd; - border-radius: 4px; - padding: 5px 10px; - font-size: 12px; - cursor: pointer; -} - -.chat-content { - display: flex; - flex: 1; - overflow: hidden; -} - -.members-panel { - width: 250px; - border-right: 1px solid #e0e0e0; - padding: 15px; - background-color: #f9f9f9; - overflow-y: auto; -} - -.members-panel h3 { - margin-top: 0; - font-size: 16px; - color: #666; - margin-bottom: 15px; -} - -.members-list { - list-style: none; padding: 0; - margin: 0 0 15px 0; -} - -.member-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 0; - border-bottom: 1px solid #eee; + box-sizing: border-box; } -.remove-member { - background: none; - border: none; - color: #999; - font-size: 16px; - cursor: pointer; +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; } -.add-member-form { - display: flex; - margin-top: 15px; - gap: 8px; -} - -.add-member-form input { - flex: 1; - padding: 8px; - border: 1px solid #ccc; - border-radius: 4px; -} - -.add-member-form button { - padding: 8px 12px; - background-color: #0078d4; - color: white; - border: none; - border-radius: 4px; - cursor: pointer; -} - -.messages-container { - flex: 1; - display: flex; - flex-direction: column; - overflow: hidden; -} - -@media (max-width: 768px) { - .chat-app { - flex-direction: column; - } - - .sidebar { - width: 100%; - height: 30%; - border-right: none; - border-bottom: 1px solid #e0e0e0; - } - - .message { - max-width: 85%; - } - - .chat-content { - flex-direction: column; - } - - .members-panel { - width: 100%; - height: 200px; - border-right: none; - border-bottom: 1px solid #e0e0e0; - } -} - -.chat-type-select { - padding: 8px; - border: 1px solid #ccc; - border-radius: 4px; - margin-bottom: 10px; +.app-container { + max-width: 100%; + overflow-x: hidden; } diff --git a/src/App.jsx b/src/App.jsx index ba129ae..4ba74ff 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,121 +1,10 @@ -import { useState } from 'react' import './App.css' -import ChatList from './components/ChatList' -import ChatWindow from './components/ChatWindow' -import NewChatButton from './components/NewChatButton' +import Stories from './components/Stories' function App() { - const [chats, setChats] = useState([ - { - id: 1, - name: 'Personal Notes', - type: 'direct', - members: [], - messages: [] - } - ]) - - const [activeChat, setActiveChat] = useState(1) - - const createChat = (name, type = 'direct', members = []) => { - const newChat = { - id: Date.now(), - name: name || `Chat ${chats.length + 1}`, - type, - members, - messages: [] - } - - setChats([...chats, newChat]) - setActiveChat(newChat.id) - } - - const createGroupChat = (name, members) => { - createChat(name, 'group', members) - } - - const createChannel = (name) => { - createChat(name, 'channel') - } - - const deleteChat = (chatId) => { - setChats(chats.filter(chat => chat.id !== chatId)) - if (activeChat === chatId) { - setActiveChat(chats[0]?.id || null) - } - } - - const addMemberToChat = (chatId, memberId, memberName) => { - setChats(chats.map(chat => { - if (chat.id === chatId) { - return { - ...chat, - members: [...chat.members, { id: memberId, name: memberName }] - } - } - return chat - })) - } - - const removeMemberFromChat = (chatId, memberId) => { - setChats(chats.map(chat => { - if (chat.id === chatId) { - return { - ...chat, - members: chat.members.filter(member => member.id !== memberId) - } - } - return chat - })) - } - - const sendMessage = (content, sender = 'You') => { - if (!content.trim()) return - - const newMessage = { - id: Date.now(), - content, - sender, - timestamp: new Date() - } - - setChats(chats.map(chat => { - if (chat.id === activeChat) { - return { - ...chat, - messages: [...chat.messages, newMessage] - } - } - return chat - })) - } - - const currentChat = chats.find(chat => chat.id === activeChat) || chats[0] - return ( -
-
- - -
- - {currentChat && ( - - )} +
+
) } diff --git a/src/components/Stories.jsx b/src/components/Stories.jsx new file mode 100644 index 0000000..a2860a5 --- /dev/null +++ b/src/components/Stories.jsx @@ -0,0 +1,54 @@ +import { useState, useEffect } from 'react' +import '../styles/Stories.css' +import StoriesList from './StoriesList' +import StoryView from './StoryView' +import storiesData from '../data/stories.json' + +function Stories() { + const [stories, setStories] = useState([]) + const [currentStoryIndex, setCurrentStoryIndex] = useState(null) + const [loading, setLoading] = useState(true) + + useEffect(() => { + const fetchStories = async () => { + try { + setStories(storiesData) + } catch (error) { + console.error('Error fetching stories:', error) + } finally { + setLoading(false) + } + } + + fetchStories() + }, []) + + const openStory = (index) => { + setCurrentStoryIndex(index) + } + + const closeStory = () => { + setCurrentStoryIndex(null) + } + + return ( +
+ {loading ? ( +
Loading stories...
+ ) : ( + <> + + {currentStoryIndex !== null && ( + + )} + + )} +
+ ) +} + +export default Stories \ No newline at end of file diff --git a/src/components/StoriesList.jsx b/src/components/StoriesList.jsx new file mode 100644 index 0000000..ac0d9eb --- /dev/null +++ b/src/components/StoriesList.jsx @@ -0,0 +1,24 @@ +import '../styles/StoriesList.css' + +function StoriesList({ stories, onStoryClick }) { + return ( +
+ {stories.map((story, index) => ( +
onStoryClick(index)} + > + {`Story + {story.username} +
+ ))} +
+ ) +} + +export default StoriesList \ No newline at end of file diff --git a/src/components/StoryView.jsx b/src/components/StoryView.jsx new file mode 100644 index 0000000..987dfac --- /dev/null +++ b/src/components/StoryView.jsx @@ -0,0 +1,106 @@ +import { useState, useEffect, useRef } from 'react' +import '../styles/StoryView.css' + +function StoryView({ stories, initialIndex, onClose }) { + const [currentIndex, setCurrentIndex] = useState(initialIndex) + const [progress, setProgress] = useState(0) + const timerRef = useRef(null) + + const currentStory = stories[currentIndex] + + useEffect(() => { + setProgress(0) + + if (timerRef.current) { + clearInterval(timerRef.current) + } + + const intervalTime = 50 // Update progress every 50ms + const totalTime = 5000 // 5 seconds total + const increment = (intervalTime / totalTime) * 100 + + timerRef.current = setInterval(() => { + setProgress(prev => { + const newProgress = prev + increment + if (newProgress >= 100) { + goToNextStory() + return 0 + } + return newProgress + }) + }, intervalTime) + + return () => { + if (timerRef.current) { + clearInterval(timerRef.current) + } + } + }, [currentIndex, stories.length]) + + const goToPrevStory = () => { + if (currentIndex > 0) { + setCurrentIndex(currentIndex - 1) + } else { + onClose() + } + } + + const goToNextStory = () => { + if (currentIndex < stories.length - 1) { + setCurrentIndex(currentIndex + 1) + } else { + onClose() + } + } + + const handleTap = (e) => { + const screenWidth = window.innerWidth + const tapPosition = e.clientX + + if (tapPosition < screenWidth / 2) { + goToPrevStory() + } else { + goToNextStory() + } + } + + return ( +
+
+
+ {stories.map((_, index) => ( +
+
+
+ ))} +
+ +
+
+
+ {currentStory.username} +
+
{currentStory.username}
+
+ +
+ +
+ Story content +
+
+
+ ) +} + +export default StoryView \ No newline at end of file diff --git a/src/data/stories.json b/src/data/stories.json new file mode 100644 index 0000000..022e6ff --- /dev/null +++ b/src/data/stories.json @@ -0,0 +1,32 @@ +[ + { + "id": "1", + "username": "user1", + "userAvatar": "https://via.placeholder.com/50", + "imageUrl": "https://cdn.dummyjson.com/product-images/beauty/essence-mascara-lash-princess/1.webp" + }, + { + "id": "2", + "username": "user2", + "userAvatar": "https://cdn.dummyjson.com/product-images/beauty/powder-canister/thumbnail.webp", + "imageUrl": "https://cdn.dummyjson.com/product-images/beauty/powder-canister/1.webp" + }, + { + "id": "3", + "username": "user3", + "userAvatar": "https://cdn.dummyjson.com/product-images/beauty/red-lipstick/thumbnail.webp", + "imageUrl": "https://cdn.dummyjson.com/product-images/beauty/red-lipstick/1.webp" + }, + { + "id": "4", + "username": "user4", + "userAvatar": "https://cdn.dummyjson.com/product-images/beauty/red-nail-polish/thumbnail.webp", + "imageUrl": "https://cdn.dummyjson.com/product-images/beauty/red-nail-polish/1.webp" + }, + { + "id": "5", + "username": "user5", + "userAvatar": "https://cdn.dummyjson.com/product-images/fragrances/calvin-klein-ck-one/thumbnail.webp", + "imageUrl": "https://cdn.dummyjson.com/product-images/fragrances/calvin-klein-ck-one/1.webp" + } +] \ No newline at end of file diff --git a/src/styles/Stories.css b/src/styles/Stories.css new file mode 100644 index 0000000..2bc6ae7 --- /dev/null +++ b/src/styles/Stories.css @@ -0,0 +1,12 @@ +.stories-container { + width: 100%; + max-width: 500px; + margin: 0 auto; + padding: 10px; +} + +.loading { + text-align: center; + padding: 20px; + font-size: 16px; +} \ No newline at end of file diff --git a/src/styles/StoriesList.css b/src/styles/StoriesList.css new file mode 100644 index 0000000..c97d8a5 --- /dev/null +++ b/src/styles/StoriesList.css @@ -0,0 +1,36 @@ +.stories-list { + display: flex; + overflow-x: auto; + padding: 10px 0; + gap: 15px; + scrollbar-width: none; +} + +.stories-list::-webkit-scrollbar { + display: none; /* Chrome, Safari, Edge */ +} + +.story-item { + display: flex; + flex-direction: column; + align-items: center; + cursor: pointer; +} + +.story-thumbnail { + width: 60px; + height: 60px; + border-radius: 50%; + object-fit: cover; + border: 2px solid #e1306c; + padding: 2px; +} + +.story-username { + font-size: 12px; + margin-top: 5px; + max-width: 70px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} \ No newline at end of file diff --git a/src/styles/StoryView.css b/src/styles/StoryView.css new file mode 100644 index 0000000..a055b2f --- /dev/null +++ b/src/styles/StoryView.css @@ -0,0 +1,98 @@ +.story-view-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.9); + z-index: 1000; + display: flex; + justify-content: center; + align-items: center; +} + +.story-view { + position: relative; + width: 100%; + height: 100%; + max-width: 500px; + display: flex; + flex-direction: column; +} + +.progress-container { + display: flex; + gap: 2px; + padding: 10px; + position: absolute; + top: 0; + left: 0; + right: 0; + z-index: 10; +} + +.progress-bar-container { + height: 2px; + background-color: rgba(255, 255, 255, 0.3); + flex-grow: 1; + border-radius: 2px; + overflow: hidden; +} + +.progress-bar { + height: 100%; + background-color: white; + transition: width 0.05s linear; +} + +.story-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 15px 10px; + color: white; + position: absolute; + top: 15px; + left: 0; + right: 0; + z-index: 10; +} + +.user-info { + display: flex; + align-items: center; + gap: 10px; +} + +.user-avatar img { + width: 30px; + height: 30px; + border-radius: 50%; + object-fit: cover; +} + +.username { + font-weight: bold; +} + +.close-button { + background: none; + border: none; + color: white; + font-size: 24px; + cursor: pointer; +} + +.story-content { + flex-grow: 1; + display: flex; + justify-content: center; + align-items: center; + height: 100%; +} + +.story-image { + width: 100%; + height: 100%; + object-fit: contain; +} \ No newline at end of file From 556d1955e32fa7c472d81335a0cef28ca7aba820 Mon Sep 17 00:00:00 2001 From: Hitesh Date: Mon, 26 May 2025 21:38:43 +0530 Subject: [PATCH 2/2] Added story images --- package.json | 2 +- src/components/ChatList.jsx | 46 --------------- src/components/ChatWindow.jsx | 95 ------------------------------- src/components/MembersList.jsx | 25 -------- src/components/Message.jsx | 24 -------- src/components/MessageInput.jsx | 27 --------- src/components/MessageList.jsx | 22 ------- src/components/NewChatButton.jsx | 89 ----------------------------- src/data/image0.jpeg | Bin 0 -> 8257 bytes src/data/image2.jpeg | Bin 0 -> 10317 bytes src/data/image3.jpeg | Bin 0 -> 7520 bytes src/data/image4.jpeg | Bin 0 -> 5837 bytes src/data/image5.jpeg | Bin 0 -> 3730 bytes src/data/stories.json | 20 +++---- 14 files changed, 11 insertions(+), 339 deletions(-) delete mode 100644 src/components/ChatList.jsx delete mode 100644 src/components/ChatWindow.jsx delete mode 100644 src/components/MembersList.jsx delete mode 100644 src/components/Message.jsx delete mode 100644 src/components/MessageInput.jsx delete mode 100644 src/components/MessageList.jsx delete mode 100644 src/components/NewChatButton.jsx create mode 100644 src/data/image0.jpeg create mode 100644 src/data/image2.jpeg create mode 100644 src/data/image3.jpeg create mode 100644 src/data/image4.jpeg create mode 100644 src/data/image5.jpeg diff --git a/package.json b/package.json index 48bf766..0296aa2 100644 --- a/package.json +++ b/package.json @@ -24,4 +24,4 @@ "globals": "^16.0.0", "vite": "^6.3.5" } -} +} \ No newline at end of file diff --git a/src/components/ChatList.jsx b/src/components/ChatList.jsx deleted file mode 100644 index 7e5af6f..0000000 --- a/src/components/ChatList.jsx +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react' - -function ChatList({ chats, activeChat, onSelectChat, onDeleteChat }) { - const getChatIcon = (type) => { - if (type === 'direct') return '👤' - if (type === 'group') return '👥' - if (type === 'channel') return '#' - return '💬' - } - - return ( -
-

Chats

-
    - {chats.map(chat => ( -
  • onSelectChat(chat.id)} - > -
    - {getChatIcon(chat.type)} - {chat.name} - - {chat.type !== 'direct' && chat.members.length > 0 && ( - {chat.members.length} - )} -
    - - -
  • - ))} -
-
- ) -} - -export default ChatList diff --git a/src/components/ChatWindow.jsx b/src/components/ChatWindow.jsx deleted file mode 100644 index 1ac1cf4..0000000 --- a/src/components/ChatWindow.jsx +++ /dev/null @@ -1,95 +0,0 @@ -import React, { useState, useRef, useEffect } from 'react' -import MessageList from './MessageList' -import MessageInput from './MessageInput' - -function ChatWindow({ chat, onSendMessage, onAddMember, onRemoveMember }) { - const [showMembers, setShowMembers] = useState(false) - const [newMember, setNewMember] = useState('') - - const messagesEndRef = useRef(null) - - useEffect(() => { - messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }) - }, [chat.messages]) - - const handleAddMember = (e) => { - e.preventDefault() - if (newMember.trim()) { - onAddMember(chat.id, Date.now(), newMember) - setNewMember('') - } - } - - return ( -
-
-
-

- {chat.type !== 'direct' && ( - - {chat.type === 'group' ? '👥' : '#'} - - )} - {chat.name} -

- - {(chat.type === 'group' || chat.type === 'channel') && ( - - )} -
-
- -
- {showMembers && (chat.type === 'group' || chat.type === 'channel') && ( -
-

Members

- {chat.members.length > 0 ? ( -
    - {chat.members.map(member => ( -
  • - {member.name} - -
  • - ))} -
- ) : ( -

No members yet

- )} - -
- setNewMember(e.target.value)} - placeholder="Add member..." - /> - -
-
- )} - -
- -
-
-
- - -
- ) -} - -export default ChatWindow diff --git a/src/components/MembersList.jsx b/src/components/MembersList.jsx deleted file mode 100644 index 5f3d2c3..0000000 --- a/src/components/MembersList.jsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react' - -function MembersList({ members, onRemoveMember, chatId }) { - if (members.length === 0) { - return

No members yet

- } - - return ( -
    - {members.map(member => ( -
  • - {member.name} - -
  • - ))} -
- ) -} - -export default MembersList \ No newline at end of file diff --git a/src/components/Message.jsx b/src/components/Message.jsx deleted file mode 100644 index 277fd4a..0000000 --- a/src/components/Message.jsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react' - -function Message({ message }) { - const formatTime = (timestamp) => { - return new Intl.DateTimeFormat('en-US', { - hour: '2-digit', - minute: '2-digit' - }).format(timestamp) - } - - return ( -
-
-
- {message.sender} - {formatTime(message.timestamp)} -
-

{message.content}

-
-
- ) -} - -export default Message \ No newline at end of file diff --git a/src/components/MessageInput.jsx b/src/components/MessageInput.jsx deleted file mode 100644 index b86877c..0000000 --- a/src/components/MessageInput.jsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { useState } from 'react' - -function MessageInput({ onSendMessage, placeholder = "Type a message..." }) { - const [message, setMessage] = useState('') - - const handleSubmit = (e) => { - e.preventDefault() - if (message.trim()) { - onSendMessage(message) - setMessage('') - } - } - - return ( -
- setMessage(e.target.value)} - placeholder={placeholder} - /> - -
- ) -} - -export default MessageInput diff --git a/src/components/MessageList.jsx b/src/components/MessageList.jsx deleted file mode 100644 index fd326f5..0000000 --- a/src/components/MessageList.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react' -import Message from './Message' - -function MessageList({ messages }) { - if (messages.length === 0) { - return ( -
-

No messages yet. Start the conversation!

-
- ) - } - - return ( -
- {messages.map(message => ( - - ))} -
- ) -} - -export default MessageList \ No newline at end of file diff --git a/src/components/NewChatButton.jsx b/src/components/NewChatButton.jsx deleted file mode 100644 index 3e310ab..0000000 --- a/src/components/NewChatButton.jsx +++ /dev/null @@ -1,89 +0,0 @@ -import React, { useState } from 'react' - -function NewChatButton({ onCreateChat, onCreateGroupChat, onCreateChannel }) { - const [isCreating, setIsCreating] = useState(false) - const [chatName, setChatName] = useState('') - const [chatType, setChatType] = useState('direct') - const [members, setMembers] = useState('') - - const handleSubmit = (e) => { - e.preventDefault() - - if (chatType === 'direct') { - onCreateChat(chatName) - } else if (chatType === 'group') { - const membersList = members - .split(',') - .map(m => m.trim()) - .filter(m => m !== '') - .map(name => ({ - id: Date.now() + Math.random(), - name - })) - - onCreateGroupChat(chatName, membersList) - } else if (chatType === 'channel') { - onCreateChannel(chatName) - } - - setChatName('') - setMembers('') - setChatType('direct') - setIsCreating(false) - } - - return ( -
- {isCreating ? ( -
- setChatName(e.target.value)} - placeholder="Chat name" - autoFocus - /> - - - - {chatType === 'group' && ( - setMembers(e.target.value)} - placeholder="Members (comma-separated)" - /> - )} - -
- - -
-
- ) : ( - - )} -
- ) -} - -export default NewChatButton diff --git a/src/data/image0.jpeg b/src/data/image0.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..90e12a08de7e23da7db1adb55dbb080a61f85a71 GIT binary patch literal 8257 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 Tu!--?`{F#pIE_5?aq<5FQZ_38 literal 0 HcmV?d00001 diff --git a/src/data/image2.jpeg b/src/data/image2.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..df235701938537bd8a855fe30a608bc6e04d6f5a GIT binary patch literal 10317 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⪙IvQ%i;;qQB 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