Andrew 16 hours ago
parent
commit
cea00de59d

+ 31 - 11
package-lock.json

@@ -12,6 +12,7 @@
         "axios": "^1.10.0",
         "js-cookie": "^3.0.5",
         "nanoid": "^5.1.5",
+        "pinia": "^3.0.3",
         "vue": "^3.5.17",
         "vue-router": "^4.5.1"
       },
@@ -1758,7 +1759,6 @@
       "version": "7.7.7",
       "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz",
       "integrity": "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@vue/devtools-shared": "^7.7.7",
@@ -1774,7 +1774,6 @@
       "version": "7.7.7",
       "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz",
       "integrity": "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "rfdc": "^1.4.1"
@@ -1948,7 +1947,6 @@
       "version": "2.4.0",
       "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.4.0.tgz",
       "integrity": "sha512-5IdNxTyhXHv2UlgnPHQ0h+5ypVmkrYHzL8QT+DwFZ//2N/oNV8Ch+BCRmTJ3x6/z9Axo/cXYBc9eprsUVK/Jsg==",
-      "dev": true,
       "license": "MIT",
       "funding": {
         "url": "https://github.com/sponsors/antfu"
@@ -2138,7 +2136,6 @@
       "version": "3.0.5",
       "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
       "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "is-what": "^4.1.8"
@@ -3036,7 +3033,6 @@
       "version": "5.5.3",
       "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
       "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/human-signals": {
@@ -3192,7 +3188,6 @@
       "version": "4.1.16",
       "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
       "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=12.13"
@@ -3442,7 +3437,6 @@
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
       "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/mrmime": {
@@ -3668,7 +3662,6 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
       "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/picocolors": {
@@ -3690,6 +3683,36 @@
         "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
+    "node_modules/pinia": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.3.tgz",
+      "integrity": "sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==",
+      "license": "MIT",
+      "dependencies": {
+        "@vue/devtools-api": "^7.7.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/posva"
+      },
+      "peerDependencies": {
+        "typescript": ">=4.4.4",
+        "vue": "^2.7.0 || ^3.5.11"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/pinia/node_modules/@vue/devtools-api": {
+      "version": "7.7.7",
+      "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.7.tgz",
+      "integrity": "sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==",
+      "license": "MIT",
+      "dependencies": {
+        "@vue/devtools-kit": "^7.7.7"
+      }
+    },
     "node_modules/postcss": {
       "version": "8.5.6",
       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
@@ -3838,7 +3861,6 @@
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
       "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/rollup": {
@@ -3971,7 +3993,6 @@
       "version": "14.0.1",
       "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
       "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
-      "dev": true,
       "license": "BSD-3-Clause",
       "engines": {
         "node": ">=0.10.0"
@@ -4008,7 +4029,6 @@
       "version": "2.2.2",
       "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
       "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "copy-anything": "^3.0.2"

+ 1 - 0
package.json

@@ -15,6 +15,7 @@
     "axios": "^1.10.0",
     "js-cookie": "^3.0.5",
     "nanoid": "^5.1.5",
+    "pinia": "^3.0.3",
     "vue": "^3.5.17",
     "vue-router": "^4.5.1"
   },

BIN
public/assets/indiaTab.png


+ 19 - 5
src/App.vue

@@ -45,11 +45,11 @@ body {
 }
 
 .main {
-    width: 100vw;
-    height: 100vh;
-    margin: 0;
-    display: flex;
-    flex-direction: row;
+	width: 100vw;
+	height: 100vh;
+	margin: 0;
+	display: flex;
+	flex-direction: row;
 }
 
 @media only screen and (max-width: 768px) {
@@ -61,4 +61,18 @@ body {
         flex-direction: column;
     }
 }
+
+@keyframes interaction {
+	0% {
+		transform: scale(1);
+	}
+
+	50% {
+		transform: scale(1.2);
+	}
+
+	100% {
+		transform: scale(1);
+	}
+}
 </style>

+ 1 - 15
src/components/DesktopSidebar.vue

@@ -86,7 +86,7 @@ export default defineComponent({
             </li>
 
             <li>
-                <button>
+                <button @click="this.router.push('/explore')">
                     <Compass :size="size" />
                     <span v-if="!minimized">explore</span>
                 </button>
@@ -250,18 +250,4 @@ li {
 .searchBar:focus {
     outline: none;
 }
-
-@keyframes interaction {
-    0% {
-        transform: scale(1);
-    }
-
-    50% {
-        transform: scale(1.2);
-    }
-
-    100% {
-        transform: scale(1);
-    }
-}
 </style>

+ 52 - 0
src/components/ExploreVideo.vue

@@ -0,0 +1,52 @@
+<script lang="ts">
+import { defineComponent } from 'vue'
+import { config } from '@/main'
+import { useRouter } from 'vue-router'
+
+export default defineComponent({
+	name: 'ExploreVideo',
+	props: {
+		id: {
+			type: Number,
+			required: true,
+		}
+	},
+	data() {
+		return {
+			config,
+		}
+	},
+	setup() {
+		const router = useRouter();
+		return { router }
+	},
+})
+</script>
+
+<template>
+	<div class="explore-video" @click="this.router.push(`/explore/videos?video=${id}`)">
+		<img :src="`${config.serverURL}/video/${id}/thumbnail`" class="explore-video-thumbnail" />
+	</div>
+</template>
+
+<style scoped>
+.explore-video {
+	border-radius: 15px;
+	border: 2px solid var(--accent-color);
+	width: 200px;
+	height: 300px;
+}
+
+.explore-video:hover {
+	cursor: pointer;
+	animation-name: interaction;
+	animation-duration: 1s;
+	animation-iteration-count: infinite;
+}
+
+.explore-video-thumbnail {
+	border-radius: 15px;
+	width: 100%;
+	height: 100%;
+}
+</style>

+ 1 - 1
src/components/MobileSidebar.vue

@@ -46,7 +46,7 @@ export default defineComponent({
             </li>
 
             <li>
-                <button>
+                <button @click="this.router.push('/search')">
                     <Search :size="size" />
                     search
                 </button>

+ 8 - 15
src/components/Player.vue

@@ -12,6 +12,7 @@ import Contact from '@/components/icons/Contact.vue'
 import ArrowRight from '@/components/icons/ArrowRight.vue'
 import ThreeDots from '@/components/icons/ThreeDots.vue'
 import { useRouter } from 'vue-router'
+import Checkmark2Icon from '@/components/icons/Checkmark2.vue'
 
 export const size = 30
 export const screenHeight = window.innerHeight
@@ -88,7 +89,7 @@ export default defineComponent({
 			})
 		}
     },
-    components: {Play, Pause, Heart, Deodorant, Contact, ArrowRight, ThreeDots},
+    components: { Checkmark2Icon, Play, Pause, Heart, Deodorant, Contact, ArrowRight, ThreeDots},
 })
 </script>
 
@@ -117,6 +118,7 @@ export default defineComponent({
 				<div class="video-author" @click="this.router.push(`/profile/${information.author.id}`)">
 					<img :src="`${config.serverURL}/account/${information.author.id}/picture`" alt="profile picture" class="video-author-picture">
 					<p>{{information.author.username}}</p>
+					<Checkmark2Icon v-if="information.author.verified" class="checkmark" />
 				</div>
 
                 <p>{{ information.description }}</p>
@@ -174,20 +176,6 @@ export default defineComponent({
     animation-iteration-count: infinite;
 }
 
-@keyframes interaction {
-    0% {
-        transform: scale(1);
-    }
-
-    50% {
-        transform: scale(1.1);
-    }
-
-    100% {
-        transform: scale(1);
-    }
-}
-
 .video-interactions {
     display: flex;
     flex-direction: column;
@@ -304,4 +292,9 @@ export default defineComponent({
 	height: 50px;
 	border-radius: 100%;
 }
+
+.checkmark {
+	width: 40px;
+	height: 30px;
+}
 </style>

+ 148 - 0
src/components/PremiumProfilePicturePicker.vue

@@ -0,0 +1,148 @@
+<script lang="ts">
+import { defineComponent } from 'vue'
+import { config } from '@/main'
+import axios from 'axios'
+import { useRoute, useRouter } from 'vue-router'
+
+export default defineComponent({
+	name: 'PremiumProfilePicturePicker',
+	data() {
+		return {
+			config,
+			profilePictures: null,
+			currentProfilePicture: 0
+		}
+	},
+	created() {
+		axios
+			.get(`${config.serverURL}/account/availablePremiumProfilePictures`)
+			.then((response) => {
+				if (response.data.error) {
+					console.error('error in getting available premium profile pictures!!!')
+					return console.error(response.data.error)
+				}
+
+				this.profilePictures = response.data
+			})
+	},
+	methods: {
+		decrement() {
+			if(this.currentProfilePicture - 1 > 1) this.currentProfilePicture -= 1
+		},
+
+		increment() {
+			if(this.currentProfilePicture + 1 < this.profilePictures.length) this.currentProfilePicture += 1
+		},
+
+		select (event) {
+			event.target.disabled = true;
+			const formData = new FormData();
+			formData.set("picture_hash", `premium_${this.profilePictures[this.currentProfilePicture]}`);
+			axios.post(`${config.serverURL}/account/update`, formData, {
+				withCredentials: true
+			}).then(response => {
+				if(response.data.error) {
+					console.error("error in updating account with premium profile picture!!!");
+					console.error(response.data);
+					alert("error in updating account. try again!!!!!!");
+					return this.router.go();
+				}
+
+				alert("success!!");
+				return this.router.go();
+			})
+		}
+	},
+	setup() {
+		const router = useRouter();
+		return { router };
+	}
+})
+</script>
+
+<template>
+	<div class="main" v-if="this.profilePictures">
+		<button class="india-button" @click="decrement"><</button>
+		<div class="flex-column">
+			<h1>Premium profile picture {{this.profilePictures[this.currentProfilePicture]}}</h1>
+			<img class="pfp" :src="`${config.serverURL}/account/getPremiumProfilePicture/${this.profilePictures[this.currentProfilePicture]}`" alt="profile picture" />
+			<button class="india-button" style="display: flex; justify-content: center;" @click="select">SELECT</button>
+		</div>
+		<button class="india-button" @click="increment">></button>
+	</div>
+	<p v-else>loading</p>
+</template>
+
+<style scoped>
+.main {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100vw;
+	height: 100vh;
+	margin: 0;
+
+	background-color: var(--background-color);
+	z-index: 9990;
+
+	display: flex;
+	flex-direction: row;
+	justify-content: space-between;
+	align-items: center;
+}
+
+.india-button {
+	display: flex;
+	align-items: center;
+	gap: 10px;
+
+	padding: 10px 10px;
+	background: none;
+	color: var(--accent-color);
+	font-family: 'Pinyon Script', cursive;
+	font-size: 60px;
+
+	border-style: solid;
+	border-width: 10px 20px;
+	border-image-source: url('/assets/indiaButton.png');
+	border-image-slice: 0 80 fill;
+	border-image-repeat: stretch;
+	border-image-outset: 0;
+	border-image-width: 10px 40px;
+	border-radius: 40px;
+	background-clip: padding-box;
+}
+
+.india-button:hover {
+	animation-name: interaction;
+	animation-duration: 0.5s;
+	animation-iteration-count: infinite;
+	cursor: pointer;
+}
+
+.india-button:disabled {
+	color: var(--background-color);
+	background-color: var(--secondary-background-color);
+	border-style: none;
+	border-image-source: none;
+}
+
+.flex-column {
+	display: flex;
+	flex-direction: column;
+	justify-content: center;
+	align-content: center;
+}
+
+.pfp {
+	width: 500px;
+	height: 500px;
+}
+
+@media screen and (max-width: 1000px) {
+	.pfp {
+		width: 300px;
+		height: 300px;
+	}
+}
+</style>

+ 117 - 0
src/components/ProfileSearchResult.vue

@@ -0,0 +1,117 @@
+<script>
+import { defineComponent } from 'vue'
+import { config } from '@/main.js'
+import { useRouter } from 'vue-router'
+import Checkmark2Icon from '@/components/icons/Checkmark2.vue'
+
+export default defineComponent({
+	name: 'ProfileSearchResult',
+	components: { Checkmark2Icon },
+	computed: {
+		config() {
+			return config
+		},
+	},
+	props: {
+		id: {
+			type: String, // this is incase id = "myself"
+			required: true,
+		},
+		username: {
+			type: String,
+			required: true,
+		},
+		following: {
+			type: Number,
+			required: true,
+		},
+		followers: {
+			type: Number,
+			required: true,
+		},
+		socialCredit: {
+			type: Number,
+			required: true,
+		},
+		verified: {
+			type: Boolean,
+			required: true
+		}
+	},
+	setup() {
+		const router = useRouter();
+		return {router}
+	}
+})
+</script>
+
+<template>
+	<div class="search-result flex-row" @click="this.router.push(`/profile/${id}`)">
+		<img :src="`${config.serverURL}/account/${id}/picture`" alt="profile picture" class="profile-picture" />
+		<div class="flex-column">
+			<div class="flex-row">
+				<h2>{{ username }}</h2>
+				<Checkmark2Icon v-if="verified" class="checkmark" />
+			</div>
+			<div class="flex-row">
+				<span class="flex-row">
+					<span>{{ followers }}</span>
+					<p class="dark">followers</p>
+				</span>
+
+				<span class="flex-row">
+					<span>{{ following }}</span>
+					<p class="dark">following</p>
+				</span>
+
+				<span class="flex-row">
+					<span>{{ socialCredit }}</span>
+					<p class="dark">social credit</p>
+				</span>
+			</div>
+		</div>
+	</div>
+</template>
+
+<style scoped>
+.search-result:hover {
+	animation-name: interaction;
+	animation-duration: 0.5s;
+	animation-iteration-count: infinite;
+
+	cursor: pointer;
+}
+
+.profile-picture {
+	width: 100px;
+	height: 100px;
+	border-radius: 100%;
+}
+
+.flex-row {
+	display: flex;
+	flex-direction: row;
+	justify-content: center;
+	align-items: center;
+
+	gap: 10px;
+}
+
+.flex-column {
+	display: flex;
+	flex-direction: column;
+	justify-content: center;
+	align-items: center;
+
+	gap: 10px;
+}
+
+.checkmark {
+	width: 50px;
+	height: 40px;
+}
+
+.dark {
+	color: var(--secondary-background-color);
+}
+</style>

+ 12 - 19
src/components/ProfileVideo.vue

@@ -28,43 +28,36 @@ export default defineComponent({
 </script>
 
 <template>
-	<div class="profile-video" @click="this.router.push(`/profile/${accountId}/videos?video=${id}`)">
-		<img :src="`${config.serverURL}/video/${id}/thumbnail`" class="profile-video-thumbnail" />
+	<div class="explore-video" @click="this.router.push(`/profile/${accountId}/videos?video=${id}`)">
+		<img :src="`${config.serverURL}/video/${id}/thumbnail`" class="explore-video-thumbnail" />
 	</div>
 </template>
 
 <style scoped>
-.profile-video {
+.explore-video {
 	border-radius: 15px;
 	border: 2px solid var(--accent-color);
 	width: 200px;
 	height: 300px;
 }
 
-.profile-video:hover {
+@media screen and (max-width: 768px) {
+	.explore-video {
+		width: 100px;
+		height: 200px;
+	}
+}
+
+.explore-video:hover {
 	cursor: pointer;
 	animation-name: interaction;
 	animation-duration: 1s;
 	animation-iteration-count: infinite;
 }
 
-.profile-video-thumbnail {
+.explore-video-thumbnail {
 	border-radius: 15px;
 	width: 100%;
 	height: 100%;
 }
-
-@keyframes interaction {
-	0% {
-		transform: scale(1);
-	}
-
-	50% {
-		transform: scale(1.2);
-	}
-
-	100% {
-		transform: scale(1);
-	}
-}
 </style>

+ 20 - 1
src/components/VideoFeed.vue

@@ -16,7 +16,8 @@ export default defineComponent({
             feedIndex: 0,
             currentPlayer: "player1",
             stiffness: 550,
-            damping: 15
+            damping: 15,
+			touchInfo: []
         }
     },
     props: {
@@ -137,6 +138,13 @@ export default defineComponent({
 		signedIn() {
 			return Cookies.get('token') && Cookies.get('token').startsWith('HajeebToken')
 		},
+		handleTouch(event) {
+			if(this.animating) return;
+			this.touchInfo.push(event.touches[0].clientY);
+
+			if ((this.touchInfo[this.touchInfo.length - 1] - this.touchInfo[0]) > 300) this.scrollUp();
+			if ((this.touchInfo[0] - this.touchInfo[this.touchInfo.length - 1]) > 300) this.scrollDown();
+		}
     },
     created () {
         // initial setup for players
@@ -144,6 +152,15 @@ export default defineComponent({
         this.player2 = this.feed[this.feedIndex + 1];
 
         document.addEventListener("wheel", this.handleScroll);
+		document.addEventListener("touchmove", this.handleTouch);
+		document.addEventListener("touchstart", (event) => {
+			this.touchInfo = [];
+			this.touchInfo.push(event.touches[0].clientY);
+		});
+
+		document.addEventListener("touchend", (event) => {
+			this.touchInfo = [];
+		});
     },
 	mounted () {
 		console.log("peepee")
@@ -171,6 +188,7 @@ export default defineComponent({
                 shares: player1?.shares ?? 13242,
                 author: {
 					username: player1?.author?.username ?? 'johnclapper',
+					verified: player1?.author?.verified ?? false,
 					id: player1?.author?.id ?? 1,
 				}
             }"
@@ -189,6 +207,7 @@ export default defineComponent({
                 shares: player2?.shares ?? 13242,
                 author: {
 					username: player2?.author?.username ?? 'johnclapper',
+					verified: player2?.author?.verified ?? false,
 					id: player2?.author?.id ?? 1,
 				}
             }"

+ 18 - 21
src/components/VideoSearchResult.vue

@@ -6,6 +6,7 @@ import Heart from '@/components/icons/Heart.vue'
 import Contact from '@/components/icons/Contact.vue'
 import ArrowRight from '@/components/icons/ArrowRight.vue'
 import { useRouter } from 'vue-router'
+import Checkmark2Icon from '@/components/icons/Checkmark2.vue'
 
 export default defineComponent({
     name: 'VideoSearchResult',
@@ -47,21 +48,30 @@ export default defineComponent({
         shares: {
             type: Number,
             required: true,
-        }
+        },
+		authorId: {
+			type: Number,
+			required: true,
+		},
+		verified: {
+			type: Boolean,
+			required: true
+		}
     },
 
-    components: {Heart, Deodorant, Contact, ArrowRight},
+    components: { Checkmark2Icon, Heart, Deodorant, Contact, ArrowRight},
 })
 </script>
 
 <template>
     <div class="search-result">
-        <img :src="`${config.serverURL}/video/${id}/thumbnail`" class="search-result-thumbnail" />
+        <img :src="`${config.serverURL}/video/${id}/thumbnail`" class="search-result-thumbnail" @click="this.router.push(`/explore/videos?video=${id}`)" />
         <div class="search-result-details">
-            <h1>{{title}}</h1>
+            <h1 @click="this.router.push(`/explore/videos?video=${id}`)">{{title}}</h1>
             <span class="search-result-author" @click="this.router.push(`/profile/${id}`)">
-					<img :src="`${config.serverURL}/account/${id}/picture`" class="search-result-author-image" />
+					<img :src="`${config.serverURL}/account/${authorId}/picture`" class="search-result-author-image" />
 					<p>{{author}}</p>
+					<Checkmark2Icon class="checkmark" v-if="verified" />
 				</span>
             <div class="search-result-interactions">
 					<span class="search-result-interaction">
@@ -114,10 +124,6 @@ export default defineComponent({
     animation-iteration-count: infinite;
 }
 
-.search-result-details h1 {
-    line-height: 10px;
-}
-
 .search-result-details h1:hover {
     cursor: pointer;
     animation-name: interaction;
@@ -164,17 +170,8 @@ export default defineComponent({
     gap: 10px;
 }
 
-@keyframes interaction {
-    0% {
-        transform: scale(1);
-    }
-
-    50% {
-        transform: scale(1.1);
-    }
-
-    100% {
-        transform: scale(1);
-    }
+.checkmark {
+	width: 40px;
+	height: 30px;
 }
 </style>

+ 41 - 29
src/router/index.js

@@ -6,46 +6,58 @@ import LoginView from '../views/LoginView.vue'
 import UploadView from '../views/UploadView.vue'
 import UpdateAccountView from '@/views/UpdateAccountView.vue'
 import ProfileVideosView from '@/views/ProfileVideosView.vue'
+import ExploreView from '@/views/ExploreView.vue'
+import ExploreVideosView from '@/views/ExploreVideosView.vue'
 
 const router = createRouter({
-    history: createWebHistory(import.meta.env.BASE_URL),
-    routes: [
-        {
-            path: '/',
-            name: 'home',
-            component: HomeView,
-        },
-        {
-            path: '/profile/:id',
-            name: 'about',
-            component: ProfileView,
-        },
+	history: createWebHistory(import.meta.env.BASE_URL),
+	routes: [
+		{
+			path: '/',
+			name: 'home',
+			component: HomeView,
+		},
+		{
+			path: '/profile/:id',
+			name: 'about',
+			component: ProfileView,
+		},
 		{
 			path: '/profile/:id/videos',
 			name: 'profileVideos',
 			component: ProfileVideosView,
 		},
-        {
-            path: '/search',
-            name: 'search',
-            component: SearchView,
-        },
-        {
-            path: '/login',
-            name: 'login',
-            component: LoginView,
-        },
-        {
-            path: '/upload',
-            name: 'upload',
-            component: UploadView
-        },
+		{
+			path: '/search',
+			name: 'search',
+			component: SearchView,
+		},
+		{
+			path: '/login',
+			name: 'login',
+			component: LoginView,
+		},
+		{
+			path: '/upload',
+			name: 'upload',
+			component: UploadView,
+		},
 		{
 			path: '/updateAccount',
 			name: 'updateAccount',
-			component: UpdateAccountView
+			component: UpdateAccountView,
+		},
+		{
+			path: '/explore',
+			name: 'explore',
+			component: ExploreView,
+		},
+		{
+			path: '/explore/videos',
+			name: 'exploreVideos',
+			component: ExploreVideosView
 		}
-    ],
+	],
 })
 
 export default router

+ 48 - 0
src/views/ExploreVideosView.vue

@@ -0,0 +1,48 @@
+<script>
+import { defineComponent } from 'vue'
+import VideoFeed from '@/components/VideoFeed.vue'
+import Sidebar from '@/components/Sidebar.vue'
+import axios from 'axios'
+import { config } from '@/main.js'
+
+export default defineComponent({
+	name: 'ExploreVideosView',
+	components: { Sidebar, VideoFeed },
+	created () {
+		const searchParams = new URLSearchParams(window.location.search);
+		if(searchParams.get('video')) this.url = `${config.serverURL}/video/explore?video=${searchParams.get('video')}`
+		else this.url = `${config.serverURL}/video/explore`
+
+		console.log("weener");
+		// Fetch feed data //
+		axios
+			.get(this.url, {
+				withCredentials: true,
+			})
+			.then((response) => {
+				if (response.data.error) return;
+				this.data = response.data
+				console.log(this.data)
+			})
+			.catch((error) => {
+				console.error('Error in getting feed!')
+				console.error(error)
+			})
+	},
+	data () {
+		return {
+			data: null
+		}
+	}
+})
+</script>
+
+<template>
+	<div class="main">
+		<Sidebar />
+		<VideoFeed v-if="this.data" :feed="this.data" />
+		<p v-else>loading</p>
+	</div>
+</template>
+
+<style scoped></style>

+ 66 - 0
src/views/ExploreView.vue

@@ -0,0 +1,66 @@
+<script>
+import { defineComponent } from 'vue'
+import Sidebar from '@/components/Sidebar.vue'
+import axios from 'axios'
+import { config } from '@/main'
+import ExploreVideo from '@/components/ExploreVideo.vue'
+
+export default defineComponent({
+	name: 'ExploreView',
+	components: { ExploreVideo, Sidebar },
+	created() {
+		// Fetch explore data //
+		axios
+			.get(`${config.serverURL}/video/explore`, {
+				withCredentials: true,
+			})
+			.then((response) => {
+				if (response.data.error) return
+				this.data = response.data
+				console.log(this.data)
+			})
+			.catch((error) => {
+				console.error('Error in getting feed!')
+				console.error(error)
+			})
+	},
+	data() {
+		return {
+			data: null,
+		}
+	},
+})
+</script>
+
+<template>
+	<div class="main">
+		<Sidebar />
+		<div class="videos" v-if="this.data">
+			<ExploreVideo :id="video.id" v-for="video in this.data" />
+		</div>
+		<p v-else>loading</p>
+	</div>
+</template>
+
+<style scoped>
+.videos {
+	width: 100%;
+	height: 100%;
+
+	flex-grow: 1;
+	display: flex;
+	flex-wrap: wrap;
+	gap: 16px;
+	padding: 16px;
+	flex-direction: row;
+	overflow-y: scroll;
+}
+
+.main {
+	width: 100vw;
+	height: 100vh;
+	margin: 0;
+	display: flex;
+	flex-direction: row;
+}
+</style>

+ 21 - 11
src/views/HomeView.vue

@@ -7,16 +7,16 @@ import axios from 'axios'
 import { config } from '@/main'
 
 export default defineComponent({
-    name: 'HomeView',
-    components: { VideoFeed, Player, Sidebar },
-	created () {
+	name: 'HomeView',
+	components: { VideoFeed, Player, Sidebar },
+	created() {
 		// Fetch feed data //
 		axios
 			.get(`${config.serverURL}/video/feed`, {
 				withCredentials: true,
 			})
 			.then((response) => {
-				if (response.data.error) return;
+				if (response.data.error) return
 				this.data = response.data
 				console.log(this.data)
 			})
@@ -25,18 +25,28 @@ export default defineComponent({
 				console.error(error)
 			})
 	},
-	data () {
+	data() {
 		return {
-			data: null
+			data: null,
 		}
-	}
+	},
 })
 </script>
 
 <template>
-    <div class="main">
-        <Sidebar />
-        <VideoFeed v-if="this.data" :feed="this.data" />
+	<div class="main">
+		<Sidebar />
+		<VideoFeed v-if="this.data" :feed="this.data" />
 		<p v-else>loading</p>
-    </div>
+	</div>
 </template>
+
+<style scoped>
+.main {
+	width: 100vw;
+	height: 100vh;
+	margin: 0;
+	display: flex;
+	flex-direction: row;
+}
+</style>

+ 49 - 22
src/views/ProfileView.vue

@@ -6,10 +6,11 @@ import Sidebar from '@/components/Sidebar.vue'
 import axios from 'axios'
 import { useRouter } from 'vue-router'
 import Cookies from 'js-cookie'
+import Checkmark2Icon from '@/components/icons/Checkmark2.vue'
 
 export default defineComponent({
 	name: 'ProfileView',
-	components: { Sidebar, ProfileVideo },
+	components: { Checkmark2Icon, Sidebar, ProfileVideo },
 	data() {
 		return {
 			config,
@@ -23,12 +24,12 @@ export default defineComponent({
 	},
 	watch: {
 		'$route.params.id'(newId, oldId) {
-			this.data = null;
+			this.data = null
 			this.fetchData(newId)
-		}
+		},
 	},
 	created() {
-		this.fetchData(this.$route.params.id);
+		this.fetchData(this.$route.params.id)
 	},
 	methods: {
 		fetchData(id) {
@@ -70,9 +71,7 @@ export default defineComponent({
 				.catch((error) => {
 					this.videos = []
 
-					console.error(
-						'Error in getting profile id ' + id + ' videos!',
-					)
+					console.error('Error in getting profile id ' + id + ' videos!')
 					console.error(error)
 				})
 		},
@@ -100,12 +99,16 @@ export default defineComponent({
 						class="profile-picture"
 						alt="profile"
 					/>
-					<span v-if="this.data">{{ this.data.username }}</span>
+
+					<span class="profile-details" v-if="this.data">
+						<span>{{ this.data.username }}</span>
+						<Checkmark2Icon v-if="this.data.verified" class="checkmark" />
+					</span>
 					<span v-else>loading</span>
 				</span>
 
 				<span class="profile-detail">
-					<span class="profile-row">
+					<span class="profile-row" id="buttons">
 						<button class="india-button">follow</button>
 						<button class="india-button">message</button>
 						<span v-if="this.data">
@@ -118,9 +121,20 @@ export default defineComponent({
 							</button>
 						</span>
 						<span v-else>loading</span>
+
+						<span v-if="this.data">
+							<button
+								class="india-button"
+								v-if="this.data.myself"
+								@click="this.router.push('/updateAccount')"
+							>
+								edit account
+							</button>
+						</span>
+						<span v-else>loading</span>
 					</span>
 
-					<span class="profile-row">
+					<span class="profile-row" id="numbers">
 						<span class="profile-row">
 							<span v-if="this.data">{{ this.data.followers }}</span>
 							<span v-else>loading</span>
@@ -138,6 +152,12 @@ export default defineComponent({
 							<span v-else>loading</span>
 							<p class="dark">videos</p>
 						</span>
+
+						<span class="profile-row">
+							<span v-if="this.data">{{ this.data.socialCredit }}</span>
+							<span v-else>loading</span>
+							<p class="dark">social credit</p>
+						</span>
 					</span>
 
 					<span class="profile-row">
@@ -225,6 +245,7 @@ export default defineComponent({
 
 	justify-content: center;
 	align-items: center;
+	flex-wrap: wrap;
 }
 
 .india-button {
@@ -288,6 +309,8 @@ export default defineComponent({
 	flex-direction: column;
 	gap: 10px;
 	font-size: 30px;
+
+	overflow-y: scroll;
 }
 
 .bio-text {
@@ -295,6 +318,11 @@ export default defineComponent({
 	cursor: pointer;
 }
 
+.checkmark {
+	width: 40px;
+	height: 30px;
+}
+
 @media only screen and (max-width: 768px) {
 	.profile-detail {
 		font-size: 20px;
@@ -308,25 +336,24 @@ export default defineComponent({
 	.bio-panel {
 		font-size: 20px;
 	}
-}
 
-@media only screen and (max-width: 500px) {
-	.profile-detail {
-		font-size: 15px;
+	#buttons {
+		gap: 5px;
 	}
-}
 
-@keyframes interaction {
-	0% {
-		transform: scale(1);
+	#numbers {
+		gap: 10px;
+		line-height: 0px;
 	}
 
-	50% {
-		transform: scale(1.1);
+	.india-button {
+		padding: 0;
 	}
+}
 
-	100% {
-		transform: scale(1);
+@media only screen and (max-width: 500px) {
+	.profile-detail {
+		font-size: 15px;
 	}
 }
 </style>

+ 223 - 127
src/views/SearchView.vue

@@ -5,172 +5,268 @@ import Sidebar from '@/components/Sidebar.vue'
 import { config } from '@/main.js'
 import axios from 'axios'
 import VideoSearchResult from '@/components/VideoSearchResult.vue'
+import ProfileSearchResult from '@/components/ProfileSearchResult.vue'
 
 export default defineComponent({
-    name: 'SearchView',
-    components: { VideoSearchResult, Sidebar, SearchIcon },
-    methods: {
-        async search(searchQuery = null) {
-            let searchBar;
-            if(searchQuery == null) { searchBar = document.getElementById('search-bar') }
-            else { searchBar = { value: searchQuery } }
-            const searchStatus = document.getElementById('search-status');
-
-            console.log(searchBar.value);
-            if (searchBar.value.trim() === '') return (searchStatus.innerText = `no`)
-            searchStatus.innerText = 'searching!!'
-            const response = await axios.post(`${config.serverURL}/video/search`, {
-                query: searchBar.value,
-            })
-
-            if (response.data.error)
-                return (searchStatus.innerText = `search error: ${response.data.error}`)
-            if (response.data.length === 0) return (searchStatus.innerText = 'no results :(')
-
-            this.searchResults = response.data
-            searchStatus.innerText = '';
-        },
-    },
-    data() {
-        return {
-            searchResults: null,
-        }
-    },
-	mounted () {
-		const searchParams = new URLSearchParams(window.location.search);
-		if(searchParams.get('searchQuery')) this.search(searchParams.get('searchQuery'));
-	}
+	name: 'SearchView',
+	components: { ProfileSearchResult, VideoSearchResult, Sidebar, SearchIcon },
+	methods: {
+		async search(searchQuery = null) {
+			let searchBar
+			if (searchQuery == null) {
+				searchBar = document.getElementById('search-bar')
+			} else {
+				searchBar = { value: searchQuery }
+			}
+			const searchStatus = document.getElementById('search-status')
+
+			console.log(searchBar.value)
+			if (searchBar.value.trim() === '') return (searchStatus.innerText = `no`)
+			searchStatus.innerText = 'searching!!'
+			let url = `${config.serverURL}/video/search`
+			if (this.selectedTab === 'accounts') url = `${config.serverURL}/account/search`
+
+			const response = await axios.post(
+				url,
+				{ query: searchBar.value },
+				{ withCredentials: true },
+			)
+
+			if (response.data.error)
+				return (searchStatus.innerText = `search error: ${response.data.error}`)
+			if (response.data.length === 0) return (searchStatus.innerText = 'no results :(')
+
+			this.searchResults = response.data
+			searchStatus.innerText = ''
+		},
+
+		selectTab(tab) {
+			this.selectedTab = tab
+			document.querySelector('.selected').classList.remove('selected')
+			document.querySelector(`#${tab}-tab`).classList.add('selected')
+			document.querySelectorAll('.search-results').forEach((div) => {
+				div.innerHTML = ''
+			})
+
+			const searchBar = document.getElementById('search-bar')
+			const searchStatus = document.getElementById('search-status')
+			if (searchBar.value.trim() !== '') this.search()
+			searchStatus.innerText = ''
+		},
+	},
+	data() {
+		return {
+			searchResults: null,
+			selectedTab: 'videos',
+		}
+	},
+	mounted() {
+		const searchParams = new URLSearchParams(window.location.search)
+		if (searchParams.get('searchQuery')) this.search(searchParams.get('searchQuery'))
+	},
 })
 </script>
 
 <template>
-    <div class="main">
-        <Sidebar />
-        <div class="search-container">
-            <div class="search-bar-container">
-                <button class="search-button" @click="search()">
-                    <SearchIcon :size="50" />
-                </button>
-                <input type="text" placeholder="Search" class="search-bar" id="search-bar" />
-            </div>
-
-            <div class="search-status" id="search-status"></div>
-            <div class="search-results" id="search-results" v-for="video in searchResults">
-                <VideoSearchResult
-                    :id="video.id"
-                    :title="video.title"
-                    :author="video.author.username"
-                    :likes="video.likes"
-                    :dislikes="video.dislikes"
-                    :comments="video.comments"
-                    :shares="video.shares"
-                />
-            </div>
-        </div>
-    </div>
+	<div class="main">
+		<Sidebar />
+		<div class="search-container">
+			<div class="tab-conglomerate">
+				<div class="tab-row">
+					<button class="india-tab selected" id="videos-tab" @click="selectTab('videos')">
+						videos
+					</button>
+					<button class="india-tab" id="accounts-tab" @click="selectTab('accounts')">
+						accounts
+					</button>
+				</div>
+				<div class="search-bar-container">
+					<button class="search-button" @click="search()">
+						<SearchIcon :size="50" />
+					</button>
+					<input type="text" placeholder="Search" class="search-bar" id="search-bar" />
+				</div>
+			</div>
+
+			<div class="search-status" id="search-status"></div>
+			<div class="search-results" id="search-results" v-if="this.selectedTab === 'videos'">
+				<VideoSearchResult
+					:id="video.id"
+					:title="video.title"
+					:author="video.author.username"
+					:author-id="video.author.id"
+					:likes="video.likes"
+					:dislikes="video.dislikes"
+					:comments="video.comments"
+					:shares="video.shares"
+					:verified="video.author.verified"
+					v-for="video in searchResults"
+				/>
+			</div>
+
+			<div class="search-results" id="search-results" v-else>
+				<ProfileSearchResult
+					:social-credit="profile.socialCredit"
+					:followers="profile.followers"
+					:following="profile.following"
+					:username="profile.username"
+					:id="profile.id"
+					:verified="profile.verified"
+					v-for="profile in searchResults"
+				/>
+			</div>
+		</div>
+	</div>
 </template>
 
 <style scoped>
 .main {
-    width: 100vw;
-    height: 100vh;
-    margin: 0;
-    display: flex;
-    flex-direction: row;
+	width: 100vw;
+	height: 100vh;
+	margin: 0;
+	display: flex;
+	flex-direction: row;
 }
 
 .search-results {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    flex-direction: column;
-    gap: 10px;
+	display: flex;
+	align-items: flex-start;
+	justify-content: flex-start;
+	padding-left: 20px;
+	flex-direction: column;
+	gap: 10px;
+
+	max-height: calc(100vh - 300px);
+	overflow-y: scroll;
+	overflow-x: hidden;
+	width: 100%;
+	flex-grow: 1;
 }
 
 .search-container {
-    /* I have to do % instead of vw and vh for the proper sizing with the sidebar !! !! !! */
-    width: 100%;
-    height: 100%;
-    margin: 0;
-
-    display: flex;
-    flex-direction: column;
-    gap: 10px;
-    padding: 20px;
-
-    justify-content: space-evenly;
-    align-items: center;
+	/* I have to do % instead of vw and vh for the proper sizing with the sidebar !! !! !! */
+	width: 100%;
+	height: 100%;
+	margin: 0;
+
+	display: flex;
+	flex-direction: column;
+	gap: 10px;
+	padding: 20px;
+
+	justify-content: space-evenly;
+	align-items: center;
 }
 
 .search-bar-container {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    gap: 10px;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	gap: 10px;
 
-    background-color: var(--text-color);
-    border-radius: 10px;
+	background-color: var(--text-color);
+	border-radius: 10px;
 
-    width: calc(100% - 200px);
+	width: calc(100% - 200px);
 }
 
 .search-bar {
-    padding: 6px;
-    font-size: 20px;
-    background-color: var(--text-color);
-    border: none;
-    color: var(--inverted-text-color);
-    font-family: "Knewave", system-ui;
-    width: calc(100% - 100px);
+	padding: 6px;
+	font-size: 20px;
+	background-color: var(--text-color);
+	border: none;
+	color: var(--inverted-text-color);
+	font-family: 'Knewave', system-ui;
+	width: calc(100% - 100px);
 }
 
 .search-bar:focus {
-    outline: none;
+	outline: none;
 }
 
 .search-button {
-    background-color: transparent;
-    border: none;
+	background-color: transparent;
+	border: none;
 }
 
 .search-button:hover {
-    cursor: pointer;
-    animation-name: interaction;
-    animation-duration: 1s;
-    animation-iteration-count: infinite;
+	cursor: pointer;
+	animation-name: interaction;
+	animation-duration: 1s;
+	animation-iteration-count: infinite;
 }
 
 .search-status {
-    position: absolute;
-    width: 100%;
-    height: 100%;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-
-    font-size: 70px;
-    font-family: "Pinyon Script", cursive;
-    color: var(--accent-color);
-    text-shadow: 5px 5px 5px #fbff00;
-
-    animation-name: interaction;
-    animation-duration: 0.2s;
-    animation-iteration-count: infinite;
-
-    pointer-events: none;
+	position: absolute;
+	width: 100%;
+	height: 100%;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+
+	font-size: 70px;
+	font-family: 'Pinyon Script', cursive;
+	color: var(--accent-color);
+	text-shadow: 5px 5px 5px #fbff00;
+
+	animation-name: interaction;
+	animation-duration: 0.2s;
+	animation-iteration-count: infinite;
+
+	pointer-events: none;
 }
 
-@keyframes interaction {
-    0% {
-        transform: scale(1);
-    }
+.india-tab {
+	padding: 10px 10px;
+	background: none;
+	color: var(--accent-color);
+	font-family: 'Pinyon Script', cursive;
+	font-size: 30px;
 
-    50% {
-        transform: scale(1.2);
-    }
+	border-style: solid;
+	border-width: 0 20px;
+	border-image-source: url('/assets/indiaTab.png');
+	border-image-slice: 0 80 fill;
+	border-radius: 40px;
+	background-clip: padding-box;
+}
+
+.india-tab:hover {
+	cursor: pointer;
+	animation-name: tab-interaction;
+	animation-duration: 0.2s;
+	animation-iteration-count: infinite;
+}
+
+.tab-conglomerate {
+	display: flex;
+	flex-direction: column;
+	gap: 0px;
+
+	width: 100%;
+}
+
+.tab-row {
+	display: flex;
+	flex-direction: row;
+	gap: 20px;
+}
 
-    100% {
-        transform: scale(1);
-    }
+.selected {
+	transform: scaleY(1.5) translateY(-20%);
+}
+
+@keyframes tab-interaction {
+	0% {
+		transform: scaleY(1) translateY(0);
+	}
+
+	50% {
+		transform: scaleY(1.5) translateY(-20%);
+	}
+
+	100% {
+		transform: scaleY(1) translateY(0);
+	}
 }
 </style>

+ 27 - 21
src/views/UpdateAccountView.vue

@@ -5,6 +5,7 @@ import Cookies from 'js-cookie'
 import { useRouter } from 'vue-router'
 import axios from 'axios'
 import { config } from '@/main.js'
+import PremiumProfilePicturePicker from '@/components/PremiumProfilePicturePicker.vue'
 
 export default defineComponent({
 	name: 'UpdateAccountView',
@@ -15,7 +16,7 @@ export default defineComponent({
 			return router.push('/profile/myself')
 		return { router }
 	},
-	components: { Sidebar },
+	components: { PremiumProfilePicturePicker, Sidebar },
 	methods: {
 		async handleSubmit(e) {
 			e.preventDefault()
@@ -23,23 +24,27 @@ export default defineComponent({
 			document.getElementById('submit').disabled = true
 
 			const formData = new FormData(e.target);
-			const response = await axios.post(`${config.serverURL}/video/upload`, formData, {
+			const response = await axios.post(`${config.serverURL}/account/update`, formData, {
 				withCredentials: true,
 			})
 
 			if(response.data.error) {
-				alert(`Upload error: ${response.data.message}`);
+				alert(`update error: ${response.data.message}`);
 				return console.error(response.data);
 			}
 
 			if(response.data.id) {
-				alert(`Video uploaded successfully!`);
+				alert(`Account updated successfully!`);
 				return this.router.push(`/profile/myself`);
 			}
 		},
 		signedIn() {
 			return Cookies.get('token') && Cookies.get('token').startsWith('HajeebToken')
 		},
+		premium() {
+			document.getElementById('submit').disabled = true;
+			document.getElementById('picker').classList.remove('hidden');
+		}
 	},
 	data () {
 		return {
@@ -51,6 +56,7 @@ export default defineComponent({
 
 <template>
 	<div class="main">
+		<PremiumProfilePicturePicker class="hidden" id="picker" />
 		<Sidebar />
 		<div class="update-container">
 			<form class="update" id="form" @submit="handleSubmit" enctype="multipart/form-data">
@@ -63,7 +69,7 @@ export default defineComponent({
 					accept="image/png, image/jpeg, image/jpg, image/webp"
 				/>
 				<h1>OR pick a PREMIUM profile picture!!!</h1>
-				<button class="india-button">PREMIUM profile PICTURES!!!</button>
+				<button @click="premium" class="india-button">PREMIUM profile PICTURES!!!</button>
 				<input type="text" placeholder="biography" name="bio" />
 				<input type="submit" value="update Account" id="submit" />
 			</form>
@@ -73,8 +79,8 @@ export default defineComponent({
 
 <style scoped>
 .update-container {
-	width: 100vw;
-	height: 100vh;
+	width: 100%;
+	height: 100%;
 	margin: 0;
 	position: absolute;
 
@@ -84,6 +90,20 @@ export default defineComponent({
 	top: 0;
 }
 
+@media screen and (max-width: 580px) {
+	.update-container {
+		font-size: 10px;
+	}
+
+	input {
+		font-size: 15px !important; /* i love css */
+	}
+}
+
+.hidden {
+	display: none;
+}
+
 .update {
 	background-color: var(--secondary-background-color);
 	color: white;
@@ -144,18 +164,4 @@ input:focus {
 	height: 100px;
 	border-radius: 100%;
 }
-
-@keyframes interaction {
-	0% {
-		transform: scale(1);
-	}
-
-	50% {
-		transform: scale(1.2);
-	}
-
-	100% {
-		transform: scale(1);
-	}
-}
 </style>