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..0296aa2 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",
@@ -24,4 +24,4 @@
"globals": "^16.0.0",
"vite": "^6.3.5"
}
-}
+}
\ No newline at end of file
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/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 (
-
- )
-}
-
-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
- )}
-
-
-
- )}
-
-
-
-
-
-
- )
-}
-
-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 (
-
- )
-}
-
-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 ? (
-
- ) : (
-
- )}
-
- )
-}
-
-export default NewChatButton
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.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}
+
+
+
+
+
+

+
+
+
+ )
+}
+
+export default StoryView
\ No newline at end of file
diff --git a/src/data/image0.jpeg b/src/data/image0.jpeg
new file mode 100644
index 0000000..90e12a0
Binary files /dev/null and b/src/data/image0.jpeg differ
diff --git a/src/data/image2.jpeg b/src/data/image2.jpeg
new file mode 100644
index 0000000..df23570
Binary files /dev/null and b/src/data/image2.jpeg differ
diff --git a/src/data/image3.jpeg b/src/data/image3.jpeg
new file mode 100644
index 0000000..e12155c
Binary files /dev/null and b/src/data/image3.jpeg differ
diff --git a/src/data/image4.jpeg b/src/data/image4.jpeg
new file mode 100644
index 0000000..a3a873f
Binary files /dev/null and b/src/data/image4.jpeg differ
diff --git a/src/data/image5.jpeg b/src/data/image5.jpeg
new file mode 100644
index 0000000..a696b57
Binary files /dev/null and b/src/data/image5.jpeg differ
diff --git a/src/data/stories.json b/src/data/stories.json
new file mode 100644
index 0000000..cd8482d
--- /dev/null
+++ b/src/data/stories.json
@@ -0,0 +1,32 @@
+[
+ {
+ "id": "1",
+ "username": "user1",
+ "userAvatar": "src/data/image0.jpeg",
+ "imageUrl": "src/data/image0.jpeg"
+ },
+ {
+ "id": "2",
+ "username": "user2",
+ "userAvatar": "src/data/image2.jpeg",
+ "imageUrl": "src/data/image2.jpeg"
+ },
+ {
+ "id": "3",
+ "username": "user3",
+ "userAvatar": "src/data/image3.jpeg",
+ "imageUrl": "src/data/image3.jpeg"
+ },
+ {
+ "id": "4",
+ "username": "user4",
+ "userAvatar": "src/data/image4.jpeg",
+ "imageUrl": "src/data/image4.jpeg"
+ },
+ {
+ "id": "5",
+ "username": "user5",
+ "userAvatar": "src/data/image5.jpeg",
+ "imageUrl": "src/data/image5.jpeg"
+ }
+]
\ 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