diff --git a/src/App.tsx b/src/App.tsx
index 8a0f872..b67db3b 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,25 +1,5 @@
-import NavBar from "./components/NavBar";
-import VideoPlayer from "./components/VideoPlayer";
-import LiveChat from "./components/LiveChat";
-import Comments from "./components/Comments";
+import Watch from "./features/watch/Watch";
export default function App() {
- return (
- <>
-
-
- >
- );
+ return ;
}
diff --git a/src/components/LiveChat.tsx b/src/components/LiveChat.tsx
deleted file mode 100644
index 7ef6130..0000000
--- a/src/components/LiveChat.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import useMessages from "../hooks/useMessages";
-import Message from "./Message";
-
-export default function LiveChat() {
- const messages = useMessages();
-
- return (
-
- {messages.map((message) => (
-
- ))}
-
- );
-}
diff --git a/src/components/Message.tsx b/src/components/Message.tsx
deleted file mode 100644
index 9ca60a6..0000000
--- a/src/components/Message.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function Message({ text }: any) {
- return {text}
;
-}
diff --git a/src/features/chats/LiveChat.tsx b/src/features/chats/LiveChat.tsx
new file mode 100644
index 0000000..7b2bbd1
--- /dev/null
+++ b/src/features/chats/LiveChat.tsx
@@ -0,0 +1,52 @@
+import Message from "./Message";
+
+type LiveChatProps = {
+ addNewMessage?: (message: string) => void;
+ messages: ReadonlyArray<{
+ id: string;
+ text: string;
+ user: string;
+ timestamp: string;
+ }>;
+};
+
+export default function LiveChat({ messages, addNewMessage }: LiveChatProps) {
+ function handleNewMessage(e: React.FormEvent) {
+ e.preventDefault();
+
+ const form = e.currentTarget;
+ const formElements = form.elements as typeof form.elements & {
+ message: { value: string };
+ };
+
+ addNewMessage!(formElements.message.value);
+ form.reset();
+ }
+
+ return (
+
+
+
+ {messages.map((message) => (
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/features/chats/LiveChatContainer.tsx b/src/features/chats/LiveChatContainer.tsx
new file mode 100644
index 0000000..8b178ff
--- /dev/null
+++ b/src/features/chats/LiveChatContainer.tsx
@@ -0,0 +1,35 @@
+import { useState } from "react";
+import LiveChat from "./LiveChat";
+
+export default function LiveChatContainer() {
+ const [messages, setMessages] = useState([
+ {
+ id: "1",
+ text: "Hello, how are you?",
+ user: "John",
+ timestamp: "2020-01-01T00:00:00.000Z",
+ },
+ {
+ id: "2",
+ text: "I'm fine, thank you!",
+ user: "John",
+ timestamp: "2020-01-01T00:00:00.000Z",
+ },
+ ]);
+
+ function handleAddNewMessage(message: string) {
+ setMessages((prevMessages) => {
+ return [
+ ...prevMessages,
+ {
+ id: `${Date.now()}`,
+ text: message,
+ user: "John",
+ timestamp: new Date().toISOString(),
+ },
+ ];
+ });
+ }
+
+ return ;
+}
diff --git a/src/features/chats/LiveChatContainerRest.tsx b/src/features/chats/LiveChatContainerRest.tsx
new file mode 100644
index 0000000..8b178ff
--- /dev/null
+++ b/src/features/chats/LiveChatContainerRest.tsx
@@ -0,0 +1,35 @@
+import { useState } from "react";
+import LiveChat from "./LiveChat";
+
+export default function LiveChatContainer() {
+ const [messages, setMessages] = useState([
+ {
+ id: "1",
+ text: "Hello, how are you?",
+ user: "John",
+ timestamp: "2020-01-01T00:00:00.000Z",
+ },
+ {
+ id: "2",
+ text: "I'm fine, thank you!",
+ user: "John",
+ timestamp: "2020-01-01T00:00:00.000Z",
+ },
+ ]);
+
+ function handleAddNewMessage(message: string) {
+ setMessages((prevMessages) => {
+ return [
+ ...prevMessages,
+ {
+ id: `${Date.now()}`,
+ text: message,
+ user: "John",
+ timestamp: new Date().toISOString(),
+ },
+ ];
+ });
+ }
+
+ return ;
+}
diff --git a/src/features/chats/Message.tsx b/src/features/chats/Message.tsx
new file mode 100644
index 0000000..0e563d8
--- /dev/null
+++ b/src/features/chats/Message.tsx
@@ -0,0 +1,3 @@
+export default function Message({ text }: any) {
+ return {text}
;
+}
diff --git a/src/features/chats/MessagesProvider.tsx b/src/features/chats/MessagesProvider.tsx
new file mode 100644
index 0000000..93f88fb
--- /dev/null
+++ b/src/features/chats/MessagesProvider.tsx
@@ -0,0 +1,11 @@
+import createContextValue from "../createContextValue";
+
+type MessagesValue = {
+ id: string;
+ text: string;
+ user: string;
+ timestamp: string;
+};
+
+export const [MessagesProvider, useMessagesValue] =
+ createContextValue>("MessagesProvider");
diff --git a/src/components/Comments.tsx b/src/features/comment/Comments.tsx
similarity index 100%
rename from src/components/Comments.tsx
rename to src/features/comment/Comments.tsx
diff --git a/src/components/NavBar.tsx b/src/features/components/NavBar.tsx
similarity index 100%
rename from src/components/NavBar.tsx
rename to src/features/components/NavBar.tsx
diff --git a/src/features/createContextValue.tsx b/src/features/createContextValue.tsx
new file mode 100644
index 0000000..afdfcfe
--- /dev/null
+++ b/src/features/createContextValue.tsx
@@ -0,0 +1,46 @@
+import React, { useContext, useMemo } from "react";
+
+/**
+ * creates a Context provider and consumer hook to a provided value.
+ */
+export default function createContextValue(
+ name: string,
+ defaultValue: T | undefined = undefined
+) {
+ const ValueContext = React.createContext(defaultValue);
+
+ type ProviderProps = {
+ children: React.ReactNode;
+ value?: T;
+ };
+
+ /**
+ * Provides the value of the context.
+ * It memoizes the provided value and recompute when `value` changes.
+ */
+ function Provider({ value, children }: ProviderProps) {
+ const contextValue = useMemo(() => value ?? defaultValue, [value]);
+ return (
+
+ {children}
+
+ );
+ }
+
+ /**
+ * Reads the value of the context.
+ * Throws an error if the component is not wrapped in a Provider
+ * or if the context value is strictly undefined.
+ */
+ function useValue() {
+ const contextValue = useContext(ValueContext);
+ if (contextValue === undefined) {
+ throw new Error(
+ `use ${name} must be used within a ${name} value provider`
+ );
+ }
+ return contextValue;
+ }
+
+ return [Provider, useValue] as const;
+}
diff --git a/src/components/VideoPlayer.tsx b/src/features/video-player/VideoPlayer.tsx
similarity index 100%
rename from src/components/VideoPlayer.tsx
rename to src/features/video-player/VideoPlayer.tsx
diff --git a/src/features/watch/Watch.tsx b/src/features/watch/Watch.tsx
new file mode 100644
index 0000000..2d6841e
--- /dev/null
+++ b/src/features/watch/Watch.tsx
@@ -0,0 +1,25 @@
+import NavBar from "../components/NavBar";
+import VideoPlayer from "../video-player/VideoPlayer";
+import LiveChatContainer from "../chats/LiveChatContainer";
+import Comments from "../comment/Comments";
+
+export default function App() {
+ return (
+ <>
+
+
+ >
+ );
+}
diff --git a/src/hooks/useMessages.ts b/src/hooks/useMessages.ts
deleted file mode 100644
index 45d5dd9..0000000
--- a/src/hooks/useMessages.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-export default function useMessages() {
- return [
- {
- id: 1,
- text: "Hello, how are you?",
- user: "John",
- timestamp: "2020-01-01T00:00:00.000Z",
- },
- {
- id: 2,
- text: "I'm fine, thank you!",
- user: "John",
- timestamp: "2020-01-01T00:00:00.000Z",
- },
- ];
-}