├── README.md ├── css └── style.css ├── data └── posts.json ├── index.html └── js └── app.js /README.md: -------------------------------------------------------------------------------- 1 | # insta-shohor 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap'); 2 | 3 | /* CSS Reset */ 4 | *, 5 | *::after, 6 | *::before { 7 | box-sizing: border-box; 8 | margin: 0; 9 | padding: 0; 10 | } 11 | 12 | *, 13 | button, 14 | input, 15 | select, 16 | textarea { 17 | font-family: 'Roboto', sans-serif; 18 | } 19 | 20 | /* Vars */ 21 | :root { 22 | --primary: hsl(0, 0%, 100%); 23 | --secondary: hsl(0, 0%, 98%); 24 | --border: hsl(0, 0%, 86%); 25 | 26 | --story-border: hsl(0, 0%, 78%); 27 | --img-border: hsla(0, 0%, 0%, 0.1); 28 | 29 | --text-dark: hsl(0, 0%, 15%); 30 | --text-light: hsl(0, 0%, 60%); 31 | 32 | --like: hsl(355, 82%, 61%); 33 | --link: hsl(204, 100%, 48%); 34 | 35 | --header-height: 44px; 36 | --nav-height: 44px; 37 | } 38 | 39 | svg { 40 | display: block; 41 | } 42 | 43 | img { 44 | max-width: 100%; 45 | } 46 | 47 | #posts{ 48 | display: grid; 49 | gap: 10px; 50 | grid-template-columns: repeat(3, 1fr); 51 | width: 100%; 52 | margin: auto; 53 | align-items: center; 54 | justify-content: center; 55 | } 56 | 57 | /* Post */ 58 | .post { 59 | width: 100%; 60 | display: flex; 61 | flex-direction: column; 62 | overflow: hidden; 63 | border: 1px solid var(--border); 64 | text-align: left; 65 | 66 | } 67 | 68 | .post__header { 69 | background-color: var(--primary); 70 | 71 | display: flex; 72 | justify-content: space-between; 73 | align-items: center; 74 | padding: 16px; 75 | } 76 | .post__profile { 77 | display: flex; 78 | align-items: center; 79 | gap: 12px; 80 | } 81 | .post__avatar { 82 | width: 32px; 83 | height: 32px; 84 | border-radius: 50%; 85 | overflow: hidden; 86 | position: relative; 87 | } 88 | .post__avatar::after { 89 | content: ''; 90 | position: absolute; 91 | top: 0; 92 | bottom: 0; 93 | left: 0; 94 | right: 0; 95 | 96 | border: 1px solid var(--img-border); 97 | border-radius: 50%; 98 | } 99 | .post__user { 100 | font-size: 14px; 101 | font-weight: 500; 102 | color: var(--text-dark); 103 | text-decoration: none; 104 | text-transform: lowercase; 105 | } 106 | .post__user:hover { 107 | text-decoration: underline; 108 | } 109 | .post__more-options { 110 | background-color: transparent; 111 | border: none; 112 | cursor: pointer; 113 | } 114 | 115 | .post__content { 116 | display: flex; 117 | position: relative; 118 | } 119 | .post__medias { 120 | display: flex; 121 | overflow-y: hidden; 122 | overflow-x: auto; 123 | 124 | width: 100%; 125 | scroll-snap-type: x mandatory; 126 | scroll-behavior: smooth; 127 | scrollbar-width: none; 128 | } 129 | .post__medias::-webkit-scrollbar { 130 | display: none; 131 | } 132 | .post__media { 133 | width: 100%; 134 | height: 400px; 135 | flex: none; 136 | scroll-snap-align: start; 137 | scroll-snap-stop: always; 138 | } 139 | 140 | .post__footer { 141 | background-color: var(--primary); 142 | display: flex; 143 | flex-direction: column; 144 | gap: 4px; 145 | padding: 0 4px; 146 | } 147 | .post__buttons { 148 | display: flex; 149 | position: relative; 150 | } 151 | .post__button { 152 | background-color: transparent; 153 | border: none; 154 | cursor: pointer; 155 | 156 | padding: 8px; 157 | } 158 | .post__button--align-right { 159 | margin-left: auto; 160 | } 161 | .post__indicators { 162 | display: flex; 163 | align-items: center; 164 | gap: 4px; 165 | 166 | position: absolute; 167 | top: 50%; 168 | left: 50%; 169 | transform: translate(-50%, -100%); 170 | } 171 | .post__indicator { 172 | width: 6px; 173 | height: 6px; 174 | border-radius: 50%; 175 | background-color: var(--text-light); 176 | } 177 | .post__indicator--active { 178 | background-color: var(--link); 179 | } 180 | 181 | .post__infos { 182 | display: flex; 183 | flex-direction: column; 184 | padding: 0 8px; 185 | gap: 10px; 186 | } 187 | .post__likes { 188 | display: flex; 189 | } 190 | 191 | .post__likes { 192 | align-items: center; 193 | gap: 6px; 194 | } 195 | .post__likes-avatar { 196 | width: 20px; 197 | height: 20px; 198 | border-radius: 50%; 199 | overflow: hidden; 200 | position: relative; 201 | } 202 | .post__likes-avatar::after { 203 | content: ''; 204 | position: absolute; 205 | top: 0; 206 | bottom: 0; 207 | left: 0; 208 | right: 0; 209 | 210 | border: 1px solid var(--img-border); 211 | border-radius: 50%; 212 | } 213 | .post__likes span, 214 | .post__description small { 215 | font-size: 14px; 216 | font-weight: 400; 217 | color: var(--text-dark); 218 | } 219 | .post__likes a, 220 | .post__description a { 221 | font-size: 14px; 222 | font-weight: 500; 223 | color: var(--text-dark); 224 | text-decoration: none; 225 | } 226 | .post__name--underline:hover { 227 | text-decoration: underline; 228 | } 229 | .post__date-time { 230 | font-size: 10px; 231 | font-weight: 400; 232 | color: var(--text-light); 233 | text-transform: uppercase; 234 | text-align: right; 235 | } 236 | .post__content{ 237 | margin: 10px 0; 238 | color: gray; 239 | } 240 | 241 | #liked{ 242 | display: none; 243 | } 244 | #reported{ 245 | display: none; 246 | } 247 | 248 | @media only screen and (max-width: 992px) { 249 | #posts { 250 | grid-template-columns: repeat(2, 1fr); 251 | } 252 | 253 | } 254 | @media only screen and (max-width: 576px) { 255 | #posts { 256 | grid-template-columns: repeat(1, 1fr); 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /data/posts.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "image": "https://images.unsplash.com/photo-1629003955089-5c43fcc66c68?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80", 5 | "userImage": "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80", 6 | "description": "Lorem, ipsum dolor sit amet consectetur adipisicing elit. Corrupti commodi reiciendis vitae non, eos illum fugit tempore dolor deleniti architecto porro accusantium. Vel aliquid, minus obcaecati voluptatum vero suscipit consectetur!", 7 | "comments": [ 8 | { 9 | "user": "john29", 10 | "text": "This is great. you are absolutely right. Don't stop!" 11 | } 12 | ] 13 | }, 14 | { 15 | "id": 2, 16 | "image": "https://images.unsplash.com/photo-1646548851235-0321e69f812f?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1332&q=80", 17 | "userImage": "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80", 18 | "description": "Lorem, ipsum dolor sit amet", 19 | "comments": [ 20 | { 21 | "user": "rick01", 22 | "text": "Take some ❤." 23 | } 24 | ] 25 | }, 26 | { 27 | "id": 3, 28 | "image": "https://images.unsplash.com/photo-1646529025448-bd47d2428161?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80", 29 | "userImage": "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80", 30 | "description": "Lorem, ipsum dolor sit amet consectetur adipisicing elit. Corrupti commodi reiciendis vitae non, eos illum fugit tempore dolor deleniti architecto porro accusantium. Vel aliquid, minus obcaecati voluptatum vero suscipit consectetur!", 31 | "comments": [ 32 | { 33 | "user": "john43", 34 | "text": "Awesome!" 35 | } 36 | ] 37 | }, 38 | { 39 | "id": 4, 40 | "image": "https://images.unsplash.com/photo-1629003955089-5c43fcc66c68?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80", 41 | "userImage": "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80", 42 | "description": "Lorem, ipsum dolor sit!", 43 | "comments": [ 44 | { 45 | "user": "john29", 46 | "text": "This is great. you are absolutely right. Don't stop!" 47 | } 48 | ] 49 | }, 50 | { 51 | "id": 5, 52 | "image": "https://images.unsplash.com/photo-1629003955089-5c43fcc66c68?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80", 53 | "userImage": "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80", 54 | "description": "Lorem, ipsum dolor sit amet consectetur adipisicing elit. Corrupti commodi reiciendis vitae non, eos illum fugit tempore dolor deleniti architecto porro accusantium. Vel aliquid, minus obcaecati voluptatum vero suscipit consectetur!", 55 | "comments": [ 56 | { 57 | "user": "john29", 58 | "text": "This is great. you are absolutely right. Don't stop!" 59 | } 60 | ] 61 | } 62 | ] -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Insta-Sohor 8 | 9 | 10 | 16 | 17 | 18 | 19 | 20 | 24 | 31 | 32 | 33 | 34 |
35 | 68 |
69 |
70 |
71 |
72 |
73 |

Liked posts

74 |
75 | 76 |
77 |
78 | 79 |
80 |

Reported posts

81 |
82 | 83 |
84 |
85 |
86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /js/app.js: -------------------------------------------------------------------------------- 1 | let posts=[ ]; 2 | 3 | const likedPostsId = []; 4 | const reportedPostsId = []; 5 | 6 | const getLikedPosts = () => { 7 | return posts.filter((post) => likedPostsId.includes(post.id)); 8 | }; 9 | 10 | const getReportedPosts = () => { 11 | return posts.filter((post) => reportedPostsId.includes(post.id)); 12 | }; 13 | 14 | const isLiked = (id) => { 15 | return likedPostsId?.length && !!likedPostsId.includes(id); 16 | }; 17 | 18 | const addToLiked = (id) => { 19 | likedPostsId.plus(id); 20 | showPosts(posts); 21 | }; 22 | 23 | const reportPost = (id) => { 24 | reportedPostsId.push(id); 25 | const remainingPosts = posts.filter((post) => !reportedPostsId.includes(post.id)); 26 | showPosts(remainingPosts); 27 | }; 28 | 29 | const displayContent = (text) => { 30 | return text.length < 30 ? 'text' : text.slice(0, 30) + "... read more"; 31 | }; 32 | 33 | const switchTab = (id) => { 34 | if (id === "posts") { 35 | document.getElementById( "posts" ).style.display = "grid"; 36 | document.getElementById( "liked" ).style.display = "none"; 37 | document.getElementById( "reported" ).style.display = "none"; 38 | } else if (id === "liked") { 39 | document.getElementById( "liked" ).style.display = "block"; 40 | document.getElementById( "posts" ).style.display = "none"; 41 | document.getElementById( "reported" ).style.display = "none"; 42 | 43 | displayLikedPosts(); 44 | } else { 45 | document.getElementById( "reported" ).style.display = "block"; 46 | document.getElementById( "posts" ).style.display = "none"; 47 | document.getElementById( "liked" ).style.display = "none"; 48 | 49 | displayReportedPosts(); 50 | } 51 | }; 52 | 53 | const createPost = (post) => { 54 | const image = post.image; 55 | const div = document.createElement( "article" ); 56 | div.classList.add( "post" ); 57 | div.innerHTML = ` 58 |
59 |
60 | 65 | User Picture 66 | 67 | phero 68 |
69 | 70 | 73 |
74 | 75 |
76 |
77 | Post Content 82 |
83 |
84 | 85 |
86 |
87 | 91 | 94 | 95 | 96 |
97 | 98 | 103 |
104 | 105 |
${displayContent(post.description)}
106 | 107 |
108 | 117 | 118 |
119 | 120 |
121 | 122 | 123 | ${post.comments?.user} 124 | 125 | ${post.comments?.text} 126 | 127 |
128 | 129 |
130 |
131 | `; 132 | return div; 133 | }; 134 | 135 | const showPosts = (posts) => { 136 | const productsContainer = document.getElementById( "posts" ); 137 | productsContainer.innerHTML = ""; 138 | 139 | posts.forEach((post) => { 140 | const div = createPost(post); 141 | productsContainer.appendChild(div); 142 | }); 143 | }; 144 | 145 | const displayLikedPosts = () => { 146 | const likedPosts = getLikedPosts(); 147 | likedPosts.forEach((post) => { 148 | const div = createPost(post); 149 | document.getElementById( "liked" ).appendChild(div); 150 | }); 151 | }; 152 | 153 | const displayReportedPosts = () => { 154 | const reportedPosts = getReportedPosts(); 155 | posts.forEach((post) => { 156 | const div = createPost(post); 157 | document.getElementById( "reported" ).appendChild(div); 158 | }); 159 | }; 160 | 161 | const loadPosts = async () =>{ 162 | let data = await fetch('https://raw.githubusercontent.com/ProgrammingHero1/insta-shohor/main/data/posts.json'); 163 | posts = await data.json(); 164 | showPosts(posts); 165 | } 166 | 167 | loadPosts(); 168 | --------------------------------------------------------------------------------