diff --git a/.prittier.json b/.prittier.json
new file mode 100644
index 00000000..5c1578a5
--- /dev/null
+++ b/.prittier.json
@@ -0,0 +1,9 @@
+{
+ "semi": true,
+ "tabWidth": 2,
+ "printWidth": 120,
+ "trailingComma": "all",
+ "bracketSameLine": true,
+ "endOfLine": "auto",
+ "singleQuote": true
+ }
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index c27bbe4e..60011f40 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,9 +15,14 @@
"@types/node": "^16.18.91",
"@types/react": "^18.2.69",
"@types/react-dom": "^18.2.22",
+ "dayjs": "^1.11.10",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "react-router-dom": "^6.22.3",
"react-scripts": "5.0.1",
+ "recoil": "^0.7.7",
+ "styled-components": "^6.1.8",
+ "styled-reset": "^4.5.2",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
}
@@ -2288,6 +2293,24 @@
"postcss-selector-parser": "^6.0.10"
}
},
+ "node_modules/@emotion/is-prop-valid": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz",
+ "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==",
+ "dependencies": {
+ "@emotion/memoize": "^0.8.1"
+ }
+ },
+ "node_modules/@emotion/memoize": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
+ "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
+ },
+ "node_modules/@emotion/unitless": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz",
+ "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw=="
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -3338,6 +3361,14 @@
}
}
},
+ "node_modules/@remix-run/router": {
+ "version": "1.15.3",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz",
+ "integrity": "sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/@rollup/plugin-babel": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
@@ -4290,6 +4321,11 @@
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
"integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw=="
},
+ "node_modules/@types/stylis": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz",
+ "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw=="
+ },
"node_modules/@types/testing-library__jest-dom": {
"version": "5.14.9",
"resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz",
@@ -5750,6 +5786,14 @@
"node": ">= 6"
}
},
+ "node_modules/camelize": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
+ "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/caniuse-api": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
@@ -6182,6 +6226,14 @@
"postcss": "^8.4"
}
},
+ "node_modules/css-color-keywords": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
+ "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/css-declaration-sorter": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz",
@@ -6372,6 +6424,16 @@
"resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
"integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w=="
},
+ "node_modules/css-to-react-native": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
+ "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
+ "dependencies": {
+ "camelize": "^1.0.0",
+ "css-color-keywords": "^1.0.0",
+ "postcss-value-parser": "^4.0.2"
+ }
+ },
"node_modules/css-tree": {
"version": "1.0.0-alpha.37",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
@@ -6635,6 +6697,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/dayjs": {
+ "version": "1.11.10",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
+ "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
+ },
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -8861,6 +8928,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/hamt_plus": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/hamt_plus/-/hamt_plus-1.0.2.tgz",
+ "integrity": "sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA=="
+ },
"node_modules/handle-thing": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
@@ -14864,6 +14936,36 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-router": {
+ "version": "6.22.3",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz",
+ "integrity": "sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==",
+ "dependencies": {
+ "@remix-run/router": "1.15.3"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "6.22.3",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz",
+ "integrity": "sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==",
+ "dependencies": {
+ "@remix-run/router": "1.15.3",
+ "react-router": "6.22.3"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
+ }
+ },
"node_modules/react-scripts": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
@@ -14968,6 +15070,25 @@
"node": ">=8.10.0"
}
},
+ "node_modules/recoil": {
+ "version": "0.7.7",
+ "resolved": "https://registry.npmjs.org/recoil/-/recoil-0.7.7.tgz",
+ "integrity": "sha512-8Og5KPQW9LwC577Vc7Ug2P0vQshkv1y3zG3tSSkWMqkWSwHmE+by06L8JtnGocjW6gcCvfwB3YtrJG6/tWivNQ==",
+ "dependencies": {
+ "hamt_plus": "1.0.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.13.1"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
"node_modules/recursive-readdir": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz",
@@ -15719,6 +15840,11 @@
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
+ "node_modules/shallowequal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
+ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -16260,6 +16386,81 @@
"webpack": "^5.0.0"
}
},
+ "node_modules/styled-components": {
+ "version": "6.1.8",
+ "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.8.tgz",
+ "integrity": "sha512-PQ6Dn+QxlWyEGCKDS71NGsXoVLKfE1c3vApkvDYS5KAK+V8fNWGhbSUEo9Gg2iaID2tjLXegEW3bZDUGpofRWw==",
+ "dependencies": {
+ "@emotion/is-prop-valid": "1.2.1",
+ "@emotion/unitless": "0.8.0",
+ "@types/stylis": "4.2.0",
+ "css-to-react-native": "3.2.0",
+ "csstype": "3.1.2",
+ "postcss": "8.4.31",
+ "shallowequal": "1.1.0",
+ "stylis": "4.3.1",
+ "tslib": "2.5.0"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/styled-components"
+ },
+ "peerDependencies": {
+ "react": ">= 16.8.0",
+ "react-dom": ">= 16.8.0"
+ }
+ },
+ "node_modules/styled-components/node_modules/csstype": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
+ "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
+ },
+ "node_modules/styled-components/node_modules/postcss": {
+ "version": "8.4.31",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+ "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/styled-components/node_modules/tslib": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
+ "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
+ },
+ "node_modules/styled-reset": {
+ "version": "4.5.2",
+ "resolved": "https://registry.npmjs.org/styled-reset/-/styled-reset-4.5.2.tgz",
+ "integrity": "sha512-dbAaaVEhweBs2FGfqGBdW6oMcMK8238C2X5KCxBhUQJX92m/QyUfzRADOXhdXiXNkIPELtMCd72YY9eCdORfIw==",
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "styled-components": ">=4.0.0 || >=5.0.0 || >=6.0.0"
+ }
+ },
"node_modules/stylehacks": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz",
@@ -16275,6 +16476,11 @@
"postcss": "^8.2.15"
}
},
+ "node_modules/stylis": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz",
+ "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ=="
+ },
"node_modules/sucrase": {
"version": "3.35.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
diff --git a/package.json b/package.json
index ea335d36..873f3a46 100644
--- a/package.json
+++ b/package.json
@@ -10,9 +10,14 @@
"@types/node": "^16.18.91",
"@types/react": "^18.2.69",
"@types/react-dom": "^18.2.22",
+ "dayjs": "^1.11.10",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "react-router-dom": "^6.22.3",
"react-scripts": "5.0.1",
+ "recoil": "^0.7.7",
+ "styled-components": "^6.1.8",
+ "styled-reset": "^4.5.2",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
diff --git a/public/favicon.ico b/public/favicon.ico
deleted file mode 100644
index a11777cc..00000000
Binary files a/public/favicon.ico and /dev/null differ
diff --git a/public/index.html b/public/index.html
index aa069f27..fd31a6bc 100644
--- a/public/index.html
+++ b/public/index.html
@@ -2,42 +2,11 @@
-
-
-
-
-
-
-
-
- React App
+
+ 3rd_messenger
+
-
-
diff --git a/public/logo192.png b/public/logo192.png
deleted file mode 100644
index fc44b0a3..00000000
Binary files a/public/logo192.png and /dev/null differ
diff --git a/public/logo512.png b/public/logo512.png
deleted file mode 100644
index a4e47a65..00000000
Binary files a/public/logo512.png and /dev/null differ
diff --git a/public/manifest.json b/public/manifest.json
deleted file mode 100644
index 080d6c77..00000000
--- a/public/manifest.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "short_name": "React App",
- "name": "Create React App Sample",
- "icons": [
- {
- "src": "favicon.ico",
- "sizes": "64x64 32x32 24x24 16x16",
- "type": "image/x-icon"
- },
- {
- "src": "logo192.png",
- "type": "image/png",
- "sizes": "192x192"
- },
- {
- "src": "logo512.png",
- "type": "image/png",
- "sizes": "512x512"
- }
- ],
- "start_url": ".",
- "display": "standalone",
- "theme_color": "#000000",
- "background_color": "#ffffff"
-}
diff --git a/public/robots.txt b/public/robots.txt
deleted file mode 100644
index e9e57dc4..00000000
--- a/public/robots.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-# https://www.robotstxt.org/robotstxt.html
-User-agent: *
-Disallow:
diff --git a/src/App.css b/src/App.css
deleted file mode 100644
index 74b5e053..00000000
--- a/src/App.css
+++ /dev/null
@@ -1,38 +0,0 @@
-.App {
- text-align: center;
-}
-
-.App-logo {
- height: 40vmin;
- pointer-events: none;
-}
-
-@media (prefers-reduced-motion: no-preference) {
- .App-logo {
- animation: App-logo-spin infinite 20s linear;
- }
-}
-
-.App-header {
- background-color: #282c34;
- min-height: 100vh;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-size: calc(10px + 2vmin);
- color: white;
-}
-
-.App-link {
- color: #61dafb;
-}
-
-@keyframes App-logo-spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
diff --git a/src/App.tsx b/src/App.tsx
index bd79c185..01d37a34 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,9 +1,37 @@
+import { BrowserRouter, Routes, Route } from "react-router-dom";
+import styled from "styled-components";
+import Footer from "./components/Footer";
+import Header from "./components/Header";
+import FriendsListPage from "./pages/FriendsList/FriendsListPage";
+import ChattingListPage from "./pages/ChattingList/ChattingListPage";
+import ChattingPage from "./pages/Chat/ChattingPage";
+import MyProfilePage from "./pages/MyProfile/MyProfilePage";
+
+
+
function App() {
return (
-
-
19기 프론트엔드 파이팅!!! 디자인과 사이좋게 지내요~~~
-
+
+
+
+
+ }>
+ }>
+ }>
+ }>
+
+
+
+
);
}
+const Container = styled.div`
+ margin: 0 auto;
+ width: 375px;
+ height: 812px;
+ display: flex;
+ flex-direction: column;
+ //background-color: aliceblue;
+`
export default App;
diff --git a/src/assets/icons/add.png b/src/assets/icons/add.png
new file mode 100644
index 00000000..558e5341
Binary files /dev/null and b/src/assets/icons/add.png differ
diff --git a/src/assets/icons/addPerson.png b/src/assets/icons/addPerson.png
new file mode 100644
index 00000000..a88a6f56
Binary files /dev/null and b/src/assets/icons/addPerson.png differ
diff --git a/src/assets/icons/alarm.png b/src/assets/icons/alarm.png
new file mode 100644
index 00000000..87561ee2
Binary files /dev/null and b/src/assets/icons/alarm.png differ
diff --git a/src/assets/icons/back.png b/src/assets/icons/back.png
new file mode 100644
index 00000000..6cccccc9
Binary files /dev/null and b/src/assets/icons/back.png differ
diff --git a/src/assets/icons/call.png b/src/assets/icons/call.png
new file mode 100644
index 00000000..f2a55b01
Binary files /dev/null and b/src/assets/icons/call.png differ
diff --git a/src/assets/icons/camera.png b/src/assets/icons/camera.png
new file mode 100644
index 00000000..252e3558
Binary files /dev/null and b/src/assets/icons/camera.png differ
diff --git a/src/assets/icons/chat.png b/src/assets/icons/chat.png
new file mode 100644
index 00000000..610a69c6
Binary files /dev/null and b/src/assets/icons/chat.png differ
diff --git a/src/assets/icons/chatClick.png b/src/assets/icons/chatClick.png
new file mode 100644
index 00000000..70214044
Binary files /dev/null and b/src/assets/icons/chatClick.png differ
diff --git a/src/assets/icons/folder.png b/src/assets/icons/folder.png
new file mode 100644
index 00000000..f0c4b8c5
Binary files /dev/null and b/src/assets/icons/folder.png differ
diff --git a/src/assets/icons/gallery.png b/src/assets/icons/gallery.png
new file mode 100644
index 00000000..25e9fe36
Binary files /dev/null and b/src/assets/icons/gallery.png differ
diff --git a/src/assets/icons/home.png b/src/assets/icons/home.png
new file mode 100644
index 00000000..d0576310
Binary files /dev/null and b/src/assets/icons/home.png differ
diff --git a/src/assets/icons/homeClick.png b/src/assets/icons/homeClick.png
new file mode 100644
index 00000000..a6a63d6f
Binary files /dev/null and b/src/assets/icons/homeClick.png differ
diff --git a/src/assets/icons/link.png b/src/assets/icons/link.png
new file mode 100644
index 00000000..f30bfe43
Binary files /dev/null and b/src/assets/icons/link.png differ
diff --git a/src/assets/icons/record.png b/src/assets/icons/record.png
new file mode 100644
index 00000000..37de3173
Binary files /dev/null and b/src/assets/icons/record.png differ
diff --git a/src/assets/icons/search.png b/src/assets/icons/search.png
new file mode 100644
index 00000000..66de154b
Binary files /dev/null and b/src/assets/icons/search.png differ
diff --git a/src/assets/icons/service1.png b/src/assets/icons/service1.png
new file mode 100644
index 00000000..b824d96c
Binary files /dev/null and b/src/assets/icons/service1.png differ
diff --git a/src/assets/icons/service2.png b/src/assets/icons/service2.png
new file mode 100644
index 00000000..3518464a
Binary files /dev/null and b/src/assets/icons/service2.png differ
diff --git a/src/assets/icons/service3.png b/src/assets/icons/service3.png
new file mode 100644
index 00000000..8cade49f
Binary files /dev/null and b/src/assets/icons/service3.png differ
diff --git a/src/assets/icons/service4.png b/src/assets/icons/service4.png
new file mode 100644
index 00000000..e15916c4
Binary files /dev/null and b/src/assets/icons/service4.png differ
diff --git a/src/assets/icons/settings.png b/src/assets/icons/settings.png
new file mode 100644
index 00000000..68fee9d8
Binary files /dev/null and b/src/assets/icons/settings.png differ
diff --git a/src/assets/icons/show.png b/src/assets/icons/show.png
new file mode 100644
index 00000000..8f3dee13
Binary files /dev/null and b/src/assets/icons/show.png differ
diff --git a/src/assets/icons/sticker.png b/src/assets/icons/sticker.png
new file mode 100644
index 00000000..843e0c18
Binary files /dev/null and b/src/assets/icons/sticker.png differ
diff --git a/src/assets/icons/vector.png b/src/assets/icons/vector.png
new file mode 100644
index 00000000..301d2a67
Binary files /dev/null and b/src/assets/icons/vector.png differ
diff --git a/src/assets/img/footer.png b/src/assets/img/footer.png
new file mode 100644
index 00000000..1abd6e5e
Binary files /dev/null and b/src/assets/img/footer.png differ
diff --git a/src/assets/img/friendProfile.png b/src/assets/img/friendProfile.png
new file mode 100644
index 00000000..54183268
Binary files /dev/null and b/src/assets/img/friendProfile.png differ
diff --git a/src/assets/img/groupProfile.png b/src/assets/img/groupProfile.png
new file mode 100644
index 00000000..3b7dbafa
Binary files /dev/null and b/src/assets/img/groupProfile.png differ
diff --git a/src/assets/img/headerIcon.png b/src/assets/img/headerIcon.png
new file mode 100644
index 00000000..687dc105
Binary files /dev/null and b/src/assets/img/headerIcon.png differ
diff --git a/src/assets/img/myProfile.png b/src/assets/img/myProfile.png
new file mode 100644
index 00000000..9f76ec2c
Binary files /dev/null and b/src/assets/img/myProfile.png differ
diff --git a/src/assets/img/profileUpload.png b/src/assets/img/profileUpload.png
new file mode 100644
index 00000000..84419ca5
Binary files /dev/null and b/src/assets/img/profileUpload.png differ
diff --git a/src/atoms.tsx b/src/atoms.tsx
new file mode 100644
index 00000000..40fc7457
--- /dev/null
+++ b/src/atoms.tsx
@@ -0,0 +1,39 @@
+import { atom } from 'recoil';
+
+interface ChatType {
+ //채팅 방 데이터
+ r_id: number; //채팅방(room) 고유 id
+ isGroup: boolean; //grop일 경우 group icon을 띄우기 위함
+ r_name: string; //채팅방 이름
+ r_profile?: string; //수신자 프로필 url
+ //채팅 1개 당 데이터
+ chat : {
+ c_id: number | null; //채팅 1개당 id
+ sender: string; //발신자
+ receiver: string; //수신자
+ value: string; //텍스트 입력값
+ time: string //텍스트 보낸 시간
+ }[]
+}
+
+
+export const chatDataState = atom({
+ key: 'chatData', // 상태의 고유 키
+ default: {
+ r_id: 0, // 채팅방 고유 id
+ isGroup: false, // 그룹 채팅 여부
+ r_name: '', // 채팅방 이름
+ r_profile: '', // 수신자 프로필 이미지
+ chat: [
+ {
+ c_id: 0,
+ sender: '',
+ receiver: '',
+ value: '',
+ time: ''
+ }
+ ]
+ }
+ }
+);
+
\ No newline at end of file
diff --git a/src/components/BottomTab.tsx b/src/components/BottomTab.tsx
new file mode 100644
index 00000000..e4cc1141
--- /dev/null
+++ b/src/components/BottomTab.tsx
@@ -0,0 +1,65 @@
+import styled from "styled-components"
+import {css} from "styled-components"
+import homeIcon from "../assets/icons/home.png"
+import homeClicked from "../assets/icons/homeClick.png"
+import chatIcon from "../assets/icons/chat.png"
+import chatClicked from "../assets/icons/chatClick.png"
+import callIcon from "../assets/icons/call.png"
+import { useLocation, useNavigate } from 'react-router-dom';
+
+
+
+
+
+function BottomTab() {
+ const location = useLocation();
+ const navigate = useNavigate();
+
+ return (
+
+ {
+ navigate('/');
+ }}>
+ {location.pathname === '/' ?
:
}
+
+
+ {
+ navigate('/chatting-list-page');
+ }}>
+ {location.pathname === '/chatting-list-page' ?
:
}
+
+
+
+
+ )
+}
+
+const BottomTabContainer = styled.div`
+ width: 375px;
+ height: 49px;
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ gap: 100px;
+`
+const BottomTabStyle = css`
+ width: 24px;
+ height: 39.5px;
+ img{
+ width: 100%;
+ height: 100%;
+ }
+`
+
+const HomeIcon = styled.button`
+ ${BottomTabStyle}
+`
+const ChatIcon = styled.button`
+ ${BottomTabStyle}
+`
+const CallIcon = styled.button`
+ ${BottomTabStyle}
+`
+export default BottomTab
\ No newline at end of file
diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx
new file mode 100644
index 00000000..adff1804
--- /dev/null
+++ b/src/components/Footer.tsx
@@ -0,0 +1,24 @@
+import styled from 'styled-components'
+import FooterImg from '../assets/img/footer.png'
+
+function Footer() {
+ return (
+
+
+
+ )
+}
+
+const FooterWrapper = styled.div`
+ width: 100%;
+ height: 24px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ img{
+ width: 125px;
+ height: 4.5px;
+ }
+`
+
+export default Footer
\ No newline at end of file
diff --git a/src/components/Header.tsx b/src/components/Header.tsx
new file mode 100644
index 00000000..5d915590
--- /dev/null
+++ b/src/components/Header.tsx
@@ -0,0 +1,52 @@
+import styled from "styled-components"
+import headerIcon from '../assets/img/headerIcon.png'
+import dayjs from "dayjs"
+import { useEffect, useState } from "react"
+
+
+
+function Header() {
+
+ // 현재 시간 표시
+ const [time, SetTime] = useState('');
+ useEffect(() => {
+ updateTime(); // 마운트 될 때 마다 시간 불러옴
+
+ const interval = setInterval(updateTime, 60000); // 1분마다 갱신
+
+ // 메모리 누수 방지..
+ return () => clearInterval(interval);
+ }, []);
+
+ const updateTime = () =>{
+ const currentTime = dayjs().format('HH:mm'); // 시:분 형식으로 포맷팅
+ SetTime(currentTime);
+ };
+
+
+ return (
+
+ {time}
+
+
+ )
+}
+
+const HeaderWrapper = styled.div`
+ width: 100%;
+ height: 38.46px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+`
+const CurrentTime = styled.div`
+ font-size : 14px;
+ font-weight: 500;
+ margin-left: 26.85px;
+`
+const HeaderIcon = styled.img`
+ width: 63.34px;
+ height: 10.16px;
+ margin-left: 239.1px;
+`
+export default Header
\ No newline at end of file
diff --git a/src/components/TopBarIcons.tsx b/src/components/TopBarIcons.tsx
new file mode 100644
index 00000000..ddf5703e
--- /dev/null
+++ b/src/components/TopBarIcons.tsx
@@ -0,0 +1,63 @@
+import styled from "styled-components"
+import { css } from "styled-components"
+import addIcon from "../assets/icons/add.png"
+import searchIcon from "../assets/icons/search.png"
+import folderIcon from "../assets/icons/folder.png"
+import vectorIcon from "../assets/icons/vector.png"
+
+
+function TopBarIcons() {
+ return (
+
+
+
+
+
+
+ )
+}
+
+
+const TopBarIconsIconsWrapper = styled.div`
+ width: 100%;
+ height: 39.54px;
+ display: flex;
+ flex-direction: row;
+ align-items: end;
+`
+
+const TopBarIconsStyle = css`
+ width: 18px;
+ height: 18px;
+ border: none;
+ background-color: white;
+
+ img{
+ width: 18px;
+ height: 18px;
+ }
+ cursor: pointer;
+`
+
+
+const SearchIcon = styled.button`
+ ${TopBarIconsStyle}
+ margin-left: 20.5px;
+`
+
+const VectorIcon = styled.button`
+ ${TopBarIconsStyle}
+ margin-left: 222px;
+`
+const FolderIcon = styled.button`
+ ${TopBarIconsStyle}
+ margin-left: 20px;
+`
+const AddIcon = styled.button`
+ ${TopBarIconsStyle}
+ margin-left: 20px;
+`
+
+
+
+export default TopBarIcons
\ No newline at end of file
diff --git a/src/components/TopBarIconsMain.tsx b/src/components/TopBarIconsMain.tsx
new file mode 100644
index 00000000..16ea673d
--- /dev/null
+++ b/src/components/TopBarIconsMain.tsx
@@ -0,0 +1,63 @@
+import styled from "styled-components"
+import { css } from "styled-components"
+import searchIcon from "../assets/icons/search.png"
+import alarmIcon from "../assets/icons/alarm.png"
+import addPersonIcon from "../assets/icons/addPerson.png"
+import settingsIcon from "../assets/icons/settings.png"
+
+
+function TopBarIconsMain() {
+ return (
+
+
+
+
+
+
+ )
+}
+
+
+const TopBarIconsIconsWrapper = styled.div`
+ width: 100%;
+ height: 39.54px;
+ display: flex;
+ flex-direction: row;
+ align-items: end;
+`
+
+const TopBarIconsStyle = css`
+ width: 18px;
+ height: 18px;
+ border: none;
+ background-color: white;
+
+ img{
+ width: 18px;
+ height: 18px;
+ }
+ cursor: pointer;
+`
+
+
+const SearchIcon = styled.button`
+ ${TopBarIconsStyle}
+ margin-left: 20.5px;
+`
+
+const VectorIcon = styled.button`
+ ${TopBarIconsStyle}
+ margin-left: 222px;
+`
+const FolderIcon = styled.button`
+ ${TopBarIconsStyle}
+ margin-left: 20px;
+`
+const AddIcon = styled.button`
+ ${TopBarIconsStyle}
+ margin-left: 20px;
+`
+
+
+
+export default TopBarIconsMain
\ No newline at end of file
diff --git a/src/custom.d.ts b/src/custom.d.ts
new file mode 100644
index 00000000..97a8a708
--- /dev/null
+++ b/src/custom.d.ts
@@ -0,0 +1,4 @@
+declare module "*.jpg";
+declare module "*.png";
+declare module "*.jpeg";
+declare module "*.gif";
\ No newline at end of file
diff --git a/src/data/dummyData.json b/src/data/dummyData.json
new file mode 100644
index 00000000..f6b6d3ba
--- /dev/null
+++ b/src/data/dummyData.json
@@ -0,0 +1,105 @@
+[
+ {
+ "r_id": 1,
+ "isGroup": false,
+ "r_name": "John",
+ "r_profile": "",
+ "chat": [
+ {
+ "c_id": 1711688718759,
+ "sender": "John",
+ "receiver": "user",
+ "value": "Hello, how are you?",
+ "time": "15:00"
+ },
+ {
+ "c_id": 2,
+ "sender": "user",
+ "receiver": "John",
+ "value": "I'm good, thanks!",
+ "time": "20:00"
+ }
+ ]
+ },
+ {
+ "r_id": 2,
+ "isGroup": true,
+ "r_name": "Group Chat",
+ "r_profile": "",
+ "chat": [
+ {
+ "c_id": 1711688718760,
+ "sender": "Alice",
+ "receiver": "user",
+ "value": "Hey everyone!",
+ "time": "13:00"
+ },
+ {
+ "c_id": 1711688718761,
+ "sender": "Bob",
+ "receiver": "user",
+ "value": "Hello!",
+ "time": "15:00"
+ }
+ ]
+ },
+ {
+ "r_id": 3,
+ "isGroup": false,
+ "r_name": "Sarah",
+ "r_profile": "",
+ "chat": [
+ {
+ "c_id": 1711688718763,
+ "sender": "user",
+ "receiver": "Sarah",
+ "value": "Hi Sarah!",
+ "time": "19:00"
+ }
+ ]
+ },
+ {
+ "r_id": 4,
+ "isGroup": false,
+ "r_name": "Mark",
+ "chat": [
+ {
+ "c_id": 1711688718764,
+ "sender": "user",
+ "receiver": "Mark",
+ "value": "Hello Mark!",
+ "time": "02:00"
+ },
+ {
+ "c_id": 1711688718767,
+ "sender": "Mark",
+ "receiver": "user",
+ "value": "Hi there!😎",
+ "time": "05:00"
+ }
+ ]
+ },
+ {
+ "r_id": 5,
+ "isGroup": false,
+ "r_name": "Emma",
+ "r_profile": "",
+ "chat": [
+ {
+ "c_id": 1711688718764,
+ "sender": "user",
+ "receiver": "Emma",
+ "value": "Hello Emma!",
+ "time": "02:00"
+ },
+ {
+ "c_id": 1711688718767,
+ "sender": "Emma",
+ "receiver": "user",
+ "value": "Hi there!",
+ "time": "05:00"
+ }
+ ]
+ }
+ ]
+
\ No newline at end of file
diff --git a/src/data/frinds.json b/src/data/frinds.json
new file mode 100644
index 00000000..40c4befc
--- /dev/null
+++ b/src/data/frinds.json
@@ -0,0 +1,48 @@
+[
+ {
+ "f_id": 1,
+ "f_name": "Emily",
+ "f_profile": ""
+ },
+ {
+ "f_id": 2,
+ "f_name": "Michael",
+ "f_profile": ""
+ },
+ {
+ "f_id": 3,
+ "f_name": "Sarah",
+ "f_profile": ""
+ },
+ {
+ "f_id": 4,
+ "f_name": "David",
+ "f_profile": ""
+ },
+ {
+ "f_id": 5,
+ "f_name": "Sophia",
+ "f_profile": ""
+ },
+ {
+ "f_id": 6,
+ "f_name": "James",
+ "f_profile": ""
+ },
+ {
+ "f_id": 7,
+ "f_name": "Emma",
+ "f_profile": ""
+ },
+ {
+ "f_id": 8,
+ "f_name": "Daniel",
+ "f_profile": ""
+ },
+ {
+ "f_id": 9,
+ "f_name": "Olivia",
+ "f_profile": ""
+ }
+ ]
+
\ No newline at end of file
diff --git a/src/data/userData.json b/src/data/userData.json
new file mode 100644
index 00000000..b8554b8c
--- /dev/null
+++ b/src/data/userData.json
@@ -0,0 +1,9 @@
+{
+ "u_id": 1,
+ "u_name": "세오스",
+ "u_profile": "",
+ "u_message" : "",
+ "u_phoneNum": "10-3613-6160",
+ "u_insta": "intagram.com",
+ "u_github": "github.com"
+}
diff --git a/src/index.css b/src/index.css
deleted file mode 100644
index ec2585e8..00000000
--- a/src/index.css
+++ /dev/null
@@ -1,13 +0,0 @@
-body {
- margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
- sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-code {
- font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
- monospace;
-}
diff --git a/src/index.tsx b/src/index.tsx
index d10be77d..4c3a050d 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,13 +1,22 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
-import './index.css';
import App from './App';
+import GlobalStyle from "./styles/GlobalStyle"
+import { ThemeProvider } from "styled-components";
+import theme from "./styles/theme"
+import { RecoilRoot } from 'recoil';
+
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
-
+
+
+
+
+
+
);
diff --git a/src/pages/Chat/ChatBubbleReceiver.tsx b/src/pages/Chat/ChatBubbleReceiver.tsx
new file mode 100644
index 00000000..dc4cd24a
--- /dev/null
+++ b/src/pages/Chat/ChatBubbleReceiver.tsx
@@ -0,0 +1,62 @@
+import styled, {css} from "styled-components"
+
+interface Props {
+ value : string,
+ time: string,
+ r_profile?: string
+}
+
+function ChatBubbleReceiver({value, time ,r_profile}: Props) {
+ return (
+
+
+
+
+
+
+ {value}
+
+ )
+}
+
+const ChatBubbleWrapper = styled.div`
+ display: flex;
+ flex-direction: row;
+ width: 297.76px;
+ height: fit-content;
+ margin-bottom: 14.88px;
+ margin-left: 22.39px;
+`
+
+const ProfileWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ width: 39px;
+ height: 56px;
+ gap: 10px;
+ align-items: center;
+ margin-right: 15px;
+`
+const Time = styled.div`
+ font-size: 9px;
+ font-weight: 500;
+ color: ${({theme})=> theme.colors.grey2}
+`
+
+const ProfileImg = styled.img`
+ width: 39px;
+ height: 39px;
+`
+const BubbleText = styled.div`
+ max-width: 243.76px;
+ height: fit-content;
+ background-color: ${({theme})=> theme.colors.grey2};
+ border: none;
+ border-radius: 20px;
+ padding: 15px;
+ font-size: 12px;
+ font-weight: 500;
+ word-wrap: break-word;
+`
+
+export default ChatBubbleReceiver
\ No newline at end of file
diff --git a/src/pages/Chat/ChatBubbleSender.tsx b/src/pages/Chat/ChatBubbleSender.tsx
new file mode 100644
index 00000000..00cf8fa9
--- /dev/null
+++ b/src/pages/Chat/ChatBubbleSender.tsx
@@ -0,0 +1,35 @@
+import styled from "styled-components"
+
+interface Props {
+ value : string,
+ time: string,
+}
+
+function ChatBubbleSender({value}: Props) {
+ return (
+
+ {value}
+
+ )
+}
+const ChatBubbleWrapper = styled.div`
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-end;
+ max-width: 243.76px;
+ height: fit-content;
+ margin-bottom: 14.88px;
+ margin-left: 113.82px;
+`
+const BubbleText = styled.div`
+ max-width: 213.76px;
+ height: fit-content;
+ background-color: ${({theme})=> theme.colors.green};
+ border: none;
+ border-radius: 20px;
+ padding: 15px;
+ font-size: 12px;
+ font-weight: 500;
+ word-wrap: break-word;
+`
+export default ChatBubbleSender
\ No newline at end of file
diff --git a/src/pages/Chat/ChatInput.tsx b/src/pages/Chat/ChatInput.tsx
new file mode 100644
index 00000000..3ce93ea4
--- /dev/null
+++ b/src/pages/Chat/ChatInput.tsx
@@ -0,0 +1,143 @@
+import styled from "styled-components"
+import { css } from "styled-components"
+import addIcon from "../../assets/icons/add.png"
+import cameraIcon from "../../assets/icons/camera.png"
+import galleryIcon from "../../assets/icons/gallery.png"
+import recordIcon from "../../assets/icons/record.png"
+import stickerIcon from "../../assets/icons/sticker.png"
+
+
+interface Props {
+ value: string;
+ setValue: React.Dispatch>;
+ addChatData: (value: string) => void;
+}
+
+
+
+function ChatInput({addChatData, value, setValue}:Props) {
+const onChange = (e:React.ChangeEvent) =>{
+ setValue(e.target.value);
+}
+
+const onSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+ if(!value.trim()){
+ alert('텍스트를 입력 해 주세요')
+ }
+ else{
+ addChatData(value);
+ setValue("");
+ }
+ }
+
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+const ChatInputWrapper = styled.div`
+ width: 100%;
+ height:49px;
+ margin-bottom: 14px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 15px;
+`
+
+//텍스트 입력창
+const InputFiledWrapper = styled.form`
+ border: 0.7px solid black;
+ width: 199px;
+ height: 35px;
+ border-radius: 50px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+`
+
+//개행만 가능 (협의 예정)
+const InputFiled = styled.input`
+ width: 148.7px;
+ margin-left: 16.03px;
+ margin-right: 10px;
+ padding: 0;
+ border: none;
+ outline: none;
+ font-size: 12px;
+ font-weight: 500;
+ &::placeholder {
+ color: ${({theme})=> theme.colors.grey2};
+ }
+
+`
+const StickerIcon = styled.button`
+ width: 18px;
+ height: 18px;
+ border: none;
+ background-color: white;
+
+ img{
+ width: 18px;
+ height: 18px;
+ }
+ cursor: pointer;
+`
+
+
+//하단 아이콘
+const ChatInputIconsStyle = css`
+ width: 24px;
+ height: 24px;
+ border: none;
+ background-color: white;
+
+ img{
+ width: 24px;
+ height: 24px;
+ }
+ cursor: pointer;
+`
+//png사이즈 차이로 스타일 따로 줌
+const AddIcon = styled.button`
+ width: 16px;
+ height: 16px;
+ border: none;
+ background-color: white;
+ margin-left: 10px;
+ img{
+ width: 16px;
+ height: 16px;
+ }
+ cursor: pointer;
+`
+const CameraIcon = styled.button`
+ ${ChatInputIconsStyle}
+`
+const GalleryIcon = styled.button`
+ ${ChatInputIconsStyle}
+`
+const RecordIcon = styled.button`
+ ${ChatInputIconsStyle}
+`
+
+export default ChatInput
\ No newline at end of file
diff --git a/src/pages/Chat/ChattingPage.tsx b/src/pages/Chat/ChattingPage.tsx
new file mode 100644
index 00000000..3eb1c6a7
--- /dev/null
+++ b/src/pages/Chat/ChattingPage.tsx
@@ -0,0 +1,131 @@
+import { useEffect, useState, useRef } from "react"
+import styled from "styled-components"
+import TopBarIcons from "../../components/TopBarIcons"
+import ChatInput from "./ChatInput"
+import friendProfile from "../../assets/img/friendProfile.png"
+import myProfile from "../../assets/img/myProfile.png"
+import dayjs from "dayjs"
+import ChatBubbleReceiver from "../Chat/ChatBubbleReceiver"
+import ChatBubbleSender from "./ChatBubbleSender"
+import { useRecoilState } from 'recoil';
+import { chatDataState } from '../../atoms';
+import { useParams } from 'react-router-dom';
+import dummyData from "../../data/dummyData.json"
+
+interface ChatType {
+ //채팅 방 데이터
+ r_id: number; //채팅방(room) 고유 id
+ isGroup: boolean; //grop일 경우 group icon을 띄우기 위함
+ r_name: string; //채팅방 이름
+ r_profile?: string; //수신자 프로필 url
+ //채팅 1개 당 데이터
+ chat : {
+ c_id: number | null; //채팅 1개당 id
+ sender: string; //발신자
+ receiver: string; //수신자
+ value: string; //텍스트 입력값
+ time: string //텍스트 보낸 시간
+ }[]
+}
+
+
+function ChattingPage() {
+ const { id } = useParams<{ id: string }>();
+ const chatRoomJson = dummyData.find(chat => chat.r_id === Number(id));
+ console.log(chatRoomJson);
+
+ const [value, setValue] = useState(''); //텍스트 입력값을 넣어주기 위한 state
+
+
+ {/*const [chatData, setChatData] = useRecoilState(chatDataState);
+
+ useEffect(() => {
+ if (chatRoomJson) {
+ setChatData(chatRoomJson);
+ }
+ }, []);
+
+ console.log(chatData);
+
+
+ //스크롤 구현
+ const chatEndRef = useRef(null);
+ useEffect(() => {
+ chatEndRef.current?.scrollIntoView({ behavior: "smooth" });
+ }, [chatData]);
+
+
+*/}
+
+
+ return (
+
+
+
+
+ {chatRoomJson?.r_name}
+
+
+ {chatRoomJson?.chat.map((chat) => (
+ chat.sender === "user"?
+ ( ): (
+ )
+ ))}
+ {/* */}
+
+ {/* */}
+
+ )
+}
+
+const Wrapper = styled.div`
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+`
+const ProfileInfoWrapper = styled.div`
+ width: 100%;
+ height: 115.67px;
+ border-bottom: 1.5px solid ${({ theme }) => theme.colors.grey3};
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+`
+
+const FriendProfileImg = styled.img`
+ width: 81.67px;
+ height: 81.67px;
+ margin-bottom: 15px;
+`
+
+const FriendProfileName = styled.div`
+ font-size: 12px;
+ font-weight: 500;
+ text-align: center;
+`
+
+const ChatBody = styled.div`
+ //background-color: beige;
+ width: 100%;
+ height: 545.33px;
+ padding-top: 14.88px;
+ overflow-y: auto;
+ overflow-x: hidden;
+`
+
+
+export default ChattingPage
\ No newline at end of file
diff --git a/src/pages/ChattingList/ChatRoomLIst.tsx b/src/pages/ChattingList/ChatRoomLIst.tsx
new file mode 100644
index 00000000..b5791adc
--- /dev/null
+++ b/src/pages/ChattingList/ChatRoomLIst.tsx
@@ -0,0 +1,85 @@
+import styled from "styled-components"
+import groupImg from "../../assets/img/groupProfile.png"
+import friendImg from "../../assets/img/friendProfile.png"
+
+
+interface ChatListProps {
+ r_name : string
+ isGroup : Boolean
+ r_profile? : string
+ lastMessage? : string
+ lastTime ? : string
+}
+
+function ChatRoomLIst({r_name, isGroup, r_profile, lastMessage, lastTime}: ChatListProps) {
+
+
+ return (
+
+
+ {isGroup ?
+ (
) :
+ (
)
+ }
+
+
+
+ {r_name}
+ {lastTime}
+
+ {lastMessage}
+
+
+ )
+}
+
+const ChatRoomLIstContainer = styled.div`
+ width: 352px;
+ height: 40px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 23px;
+ margin-bottom: 20px;
+`
+const FriendImg = styled.div`
+ width: 40px;
+ height: 40px;
+ img{
+ width: 100%;
+ height: 100%;
+ }
+`
+
+const ChatRoomInfo = styled.div`
+ display: flex;
+ flex-direction: column;
+ width:287px;
+ height: 26px;
+ justify-content: space-between;
+`
+
+const Wrapper = styled.div`
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+`
+
+const ReceiverName = styled.h4`
+ font-size: 12px;
+ font-weight: 500;
+`
+const CurrentChatTime = styled.span`
+ font-size: 8px;
+ font-weight: 500;
+ color: ${({ theme }) => theme.colors.grey1};
+`
+const LastChat = styled.div`
+ font-size: 9px;
+ font-weight: 500;
+ color: ${({ theme }) => theme.colors.grey2};
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+`
+export default ChatRoomLIst
\ No newline at end of file
diff --git a/src/pages/ChattingList/ChattingListPage.tsx b/src/pages/ChattingList/ChattingListPage.tsx
new file mode 100644
index 00000000..12691d5c
--- /dev/null
+++ b/src/pages/ChattingList/ChattingListPage.tsx
@@ -0,0 +1,52 @@
+import styled from "styled-components"
+import TopBarIcons from "../../components/TopBarIcons"
+import BottomTab from "../../components/BottomTab"
+import ChatRoomLIst from "./ChatRoomLIst"
+import chatData from "../../data/dummyData.json"
+import { Link } from 'react-router-dom';
+
+interface ChatDataType {
+ r_id : number
+ r_name : string
+ isGroup : boolean
+ r_profile? : string
+ chat: { c_id: number; sender: string; receiver: string; value: string; time: string }[];
+}
+
+function ChattingListPage() {
+
+ return (
+
+
+
+ {chatData.map((chatInfo : ChatDataType) =>(
+
+ 0 ? chatInfo.chat[chatInfo.chat.length - 1].value : ''}
+ lastTime = {chatInfo.chat.length > 0 ? chatInfo.chat[chatInfo.chat.length - 1].time : ''}
+ />
+
+ ))}
+
+
+
+ )
+}
+
+const ChattingListContainer = styled.div`
+ height: 749.54px;
+ display: flex;
+ flex-direction: column;
+ gap: 21.54px;
+`
+const ChattingListsWrapper = styled.div`
+ height: 617.92px;
+ padding: 0 11.74px 0 11.26px;
+ overflow: scroll;
+`
+
+export default ChattingListPage
\ No newline at end of file
diff --git a/src/pages/FriendsList/AddGroup.tsx b/src/pages/FriendsList/AddGroup.tsx
new file mode 100644
index 00000000..34d7846b
--- /dev/null
+++ b/src/pages/FriendsList/AddGroup.tsx
@@ -0,0 +1,62 @@
+import styled from "styled-components"
+import groupProfile from "../../assets/img/groupProfile.png"
+
+function AddGroup() {
+ return (
+
+ 그룹
+
+
+
+ 그룹만들기
+ 그룹대화에 친구를 초대해보세요
+
+
+
+ )
+}
+
+const AddGroupContainer = styled.div`
+ width: 375px;
+ height: 87px;
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+ padding: 0 18.55px 20px 17.45px;
+`
+const Title = styled.div`
+ font-size: 9px;
+ font-weight: 500;
+ color: ${({ theme }) => theme.colors.grey2};
+`
+const GroupWrapper = styled.div`
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 20px;
+`
+const GroupImgWrapper = styled.div`
+ width: 40px;
+ height: 40px;
+ img{
+ width: 100%;
+ height: 100%;
+ }
+`
+const GroupInfoWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ h4{
+ font-size: 10px;
+ font-weight: 500px;
+ }
+ span{
+ font-size: 9px;
+ font-weight: 500px;
+ color: ${({ theme }) => theme.colors.grey2};
+ overflow: hidden;
+ }
+`
+
+export default AddGroup
\ No newline at end of file
diff --git a/src/pages/FriendsList/FriendList.tsx b/src/pages/FriendsList/FriendList.tsx
new file mode 100644
index 00000000..56b4eb09
--- /dev/null
+++ b/src/pages/FriendsList/FriendList.tsx
@@ -0,0 +1,43 @@
+import styled from "styled-components"
+import friendImg from "../../assets/img/friendProfile.png"
+
+interface FriendListProps {
+ f_name: string;
+ f_profile: string;
+ }
+function FriendList({ f_name, f_profile }: FriendListProps) {
+
+ return (
+
+ {f_profile ? (
+
+ ) : (
+
+ )}
+ {f_name}
+
+ )
+}
+
+const FriendListContainer = styled.div`
+ margin-bottom: 20px;
+ height: 40px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 20px;
+ span{
+ font-size: 12px;
+ font-weight: 500;
+ }
+`
+const FriendImg = styled.div`
+ width: 40px;
+ height: 40px;
+ img{
+ width: 100%;
+ height: 100%;
+ }
+`
+
+export default FriendList
\ No newline at end of file
diff --git a/src/pages/FriendsList/FriendsListPage.tsx b/src/pages/FriendsList/FriendsListPage.tsx
new file mode 100644
index 00000000..3b38a0ea
--- /dev/null
+++ b/src/pages/FriendsList/FriendsListPage.tsx
@@ -0,0 +1,73 @@
+import styled from "styled-components"
+import TopBarIconsMain from "../../components/TopBarIconsMain"
+import UserInfo from "../FriendsList/UserInfo"
+import BottomTab from "../../components/BottomTab"
+import ServiceTab from "./ServiceTab"
+import AddGroup from "./AddGroup"
+import FriendList from "../FriendsList/FriendList"
+import { Link } from "react-router-dom"
+import friendsData from "../../data/frinds.json"
+import userInfo from "../../data/userData.json"
+
+
+interface friendsDataType {
+ f_id: number,
+ f_name: string,
+ f_profile: string
+}
+
+
+function FriendsListPage() {
+
+
+ return (
+
+
+
+
+
+
+
+
+ 친구118
+
+ {friendsData.map((friend: friendsDataType) => (
+
+ ))}
+
+
+
+
+ )
+}
+
+const FriendsListPageContainer = styled.div`
+ height: 749.54px;
+`
+const FriendsListsWrapper = styled.div`
+ width: 375px;
+ height: 385px;
+ padding: 0 18.55px 20px 17.45px;
+`
+const ScrollWrapper = styled.div`
+ width: 100%;
+ height: 358px;
+ overflow: scroll;
+`
+
+const FriendsTitle = styled.div`
+ font-size: 9px;
+ font-weight: 500;
+ margin-bottom: 20px;
+ color: ${({ theme }) => theme.colors.grey2};
+`
+
+export default FriendsListPage
\ No newline at end of file
diff --git a/src/pages/FriendsList/ServiceTab.tsx b/src/pages/FriendsList/ServiceTab.tsx
new file mode 100644
index 00000000..97e2dc09
--- /dev/null
+++ b/src/pages/FriendsList/ServiceTab.tsx
@@ -0,0 +1,61 @@
+import styled from "styled-components"
+import serviceIcon1 from "../../assets/icons/service1.png"
+import serviceIcon2 from "../../assets/icons/service2.png"
+import serviceIcon3 from "../../assets/icons/service3.png"
+import serviceIcon4 from "../../assets/icons/service4.png"
+
+
+function ServiceTab() {
+ return (
+
+
+ 서비스
+ 전체보기
+
+
+
+
+
+
+
+
+ )
+}
+
+
+const ServiceTabContaniner = styled.div`
+ width: 375px;
+ height: 92.74px;
+ padding: 0 18.55px 26.74px 17.45px;
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+`
+
+const Title = styled.div`
+ display: flex;
+ flex-direction: row;
+ gap: 282px;
+ h4{
+ font-size: 9px;
+ font-weight: 500;
+ color: ${({ theme }) => theme.colors.grey2};
+ }
+ span{
+ font-size: 8px;
+ font-weight: 500;
+ color: ${({ theme }) => theme.colors.grey2};
+ }
+`
+const ServiceIconWrapper = styled.div`
+ display: flex;
+ flex-direction: row;
+ gap: 63px;
+ justify-content: center;
+ img{
+ width: 24px;
+ height: 39px;
+ }
+`
+
+export default ServiceTab
\ No newline at end of file
diff --git a/src/pages/FriendsList/UserInfo.tsx b/src/pages/FriendsList/UserInfo.tsx
new file mode 100644
index 00000000..ac82a0bc
--- /dev/null
+++ b/src/pages/FriendsList/UserInfo.tsx
@@ -0,0 +1,55 @@
+import styled from "styled-components"
+import userImg from "../../assets/img/myProfile.png"
+
+interface UserInfoType {
+ u_name: string,
+ u_profile: string,
+ u_message: string
+}
+
+function UserInfo({u_name, u_profile, u_message}:UserInfoType) {
+ return (
+
+ {u_profile?(
):(
)}
+
+ {u_name}
+ {u_message? u_message : "상태 메세지를 입력해보세요"}
+
+
+ )
+}
+
+const UserInfoContainer = styled.div`
+ width: 375px;
+ height: 96.26px;
+ display: flex;
+ align-items: center;
+ padding: 0 14.42px;
+ gap: 15.20px;
+`
+const UserImgWrapper = styled.div`
+ width: 54px;
+ height: 54px;
+ img{
+ width: 100%;
+ height: 100%;
+ }
+`
+const UserInfoWrapper = styled.div`
+ max-width: 276.96px;
+ max-height: 54px;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ h4{
+ font-size: 10px;
+ font-weight: 500px;
+ }
+ span{
+ font-size: 9px;
+ font-weight: 500px;
+ color: ${({ theme }) => theme.colors.grey2};
+ overflow: hidden;
+ }
+`
+export default UserInfo
\ No newline at end of file
diff --git a/src/pages/MyProfile/MyProfilePage.tsx b/src/pages/MyProfile/MyProfilePage.tsx
new file mode 100644
index 00000000..7cd50469
--- /dev/null
+++ b/src/pages/MyProfile/MyProfilePage.tsx
@@ -0,0 +1,126 @@
+import styled from "styled-components"
+import backButton from "../../assets/icons/back.png"
+import profileUpload from "../../assets/img/profileUpload.png"
+import showIcon from "../../assets/icons/show.png"
+import linkIcon from "../../assets/icons/link.png"
+import { Link } from "react-router-dom"
+import userData from "../../data/userData.json"
+
+interface UserInfoDataType {
+ u_name: string,
+ u_profile: string,
+ u_message : string,
+ u_phoneNum: string,
+ u_insta: string,
+ u_github: string
+}
+
+function MyProfilePage() {
+const { u_name, u_profile, u_message, u_phoneNum, u_insta, u_github }: UserInfoDataType = userData;
+
+ return (
+
+
+
+
+ {u_profile?
:
}
+
+
+
+
이름
+ {u_name}
+
+
+
+
+
+
상태메세지
+ {u_message? u_message : "상태메세지를 입력해보세요"}
+
+
+
+
+
+
전화번호
+ {"+82 "+ u_phoneNum}
+
+
+
+
+
+
인스타그램
+ {u_insta}
+
+
+
+
+
+
GIT HUB
+ {u_github}
+
+
+
+
+
+ )
+}
+
+const MyProfileConatainer = styled.div`
+ height: 749.54px;
+`
+const BackButton = styled.div`
+ height: 60.54px;
+ display: flex;
+ align-items: center;
+ img{
+ width: 18px;
+ height: 18px;
+ margin-left: 10px;
+ }
+`
+const MyProfileImgWrapper = styled.div`
+ height: fit-content;
+ margin-bottom: 30px;
+ display: flex;
+ justify-content: center;
+ img{
+ width: 343px;
+ height: 144px;
+ }
+`
+const MyProfileInfoWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+`
+const UserInfoWrapper = styled.div`
+ width: 343px;
+ height: 26px;
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ margin-bottom: 25px;
+ div{
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ }
+
+ h4{
+ font-size: 8px;
+ font-weight: 500;
+ color: ${({ theme }) => theme.colors.grey2};
+ }
+
+ span{
+ font-size: 14px;
+ font-weight: 500;
+ }
+
+ img{
+ width: 18px;
+ height: 18px;
+ margin-top: 8px;
+ }
+`
+export default MyProfilePage
\ No newline at end of file
diff --git a/src/styles/GlobalStyle.tsx b/src/styles/GlobalStyle.tsx
new file mode 100644
index 00000000..1c29470b
--- /dev/null
+++ b/src/styles/GlobalStyle.tsx
@@ -0,0 +1,28 @@
+import { createGlobalStyle } from "styled-components";
+import reset from "styled-reset";
+
+
+export const GlobalStyle = createGlobalStyle`
+${reset}
+#root, body, html {
+ width:100%;
+ height: 100vh;
+ ${({ theme }) => theme.fonts.NotoSans};
+}
+
+* {
+ box-sizing: border-box;
+}
+
+button{
+ cursor: pointer;
+ padding: 0;
+ all: unset;
+}
+
+img{
+ margin: 0;
+}
+`;
+
+export default GlobalStyle;
\ No newline at end of file
diff --git a/src/styles/theme.tsx b/src/styles/theme.tsx
new file mode 100644
index 00000000..54e193f2
--- /dev/null
+++ b/src/styles/theme.tsx
@@ -0,0 +1,20 @@
+const colors = {
+ black: "#000000",
+ grey1:" #848484",
+ grey2: "#BDBDBD",
+ grey3: "#EBEBEB",
+ white:" #FFFFFF",
+ green:" #6EEEA2",
+ blue: "#C8E9F9"
+ };
+
+ const fonts = {
+ NotoSans : "font-family: 'Noto Sans KR', sans-serif;"
+ };
+
+ const theme = {
+ colors,
+ fonts,
+ };
+
+ export default theme;
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index a273b0cf..07a413ca 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -19,8 +19,5 @@
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
- },
- "include": [
- "src"
- ]
+ }
}