7 Commits 7b4dcc4219 ... 1cd68520e1

Author SHA1 Message Date
  Andrew 1cd68520e1 vue 1 week ago
  Andrew 7b4dcc4219 stuff 2 weeks ago
  Andrew 22c90d3766 stuff 3 weeks ago
  Andrew e749e6a744 search resultss 3 weeks ago
  Andrew 5c23b4a86d stuff 3 weeks ago
  Andrew d4b87967fd stuff 3 weeks ago
  Andrew e6f4456b55 initial commit 3 weeks ago
100 changed files with 2055 additions and 1055 deletions
  1. 9 0
      .editorconfig
  2. 0 1
      .env
  3. 1 0
      .gitattributes
  4. 7 1
      .gitignore
  5. 7 0
      .prettierrc.json
  6. 8 0
      .vscode/extensions.json
  7. 30 7
      README.md
  8. 0 33
      eslint.config.js
  9. 13 23
      index.html
  10. 8 0
      jsconfig.json
  11. 432 166
      package-lock.json
  12. 16 17
      package.json
  13. BIN
      public/assets/16_final.mp4
  14. BIN
      public/assets/34_final.mp4
  15. BIN
      public/assets/7_final.mp4
  16. 0 0
      public/assets/banner.png
  17. 0 0
      public/assets/hajeebtok.png
  18. 0 0
      public/assets/logo.png
  19. BIN
      public/favicon.ico
  20. 0 0
      public/icons/ArrowDown.png
  21. 0 0
      public/icons/ArrowLeft.png
  22. 0 0
      public/icons/ArrowRight.png
  23. 0 0
      public/icons/ArrowTopLeft.png
  24. 0 0
      public/icons/ArrowTopRight.png
  25. 0 0
      public/icons/ArrowUp.png
  26. 0 0
      public/icons/Checkmark.png
  27. 0 0
      public/icons/Checkmark2.png
  28. 0 0
      public/icons/Compass.png
  29. 0 0
      public/icons/Contact.png
  30. 0 0
      public/icons/Deodorant.png
  31. 0 0
      public/icons/Edit.png
  32. 0 0
      public/icons/Gear.png
  33. 0 0
      public/icons/Grandpa.png
  34. 0 0
      public/icons/Heart.png
  35. 0 0
      public/icons/Home.png
  36. 0 0
      public/icons/Knife.png
  37. 0 0
      public/icons/Minus.png
  38. 0 0
      public/icons/Pause.png
  39. 0 0
      public/icons/Person.png
  40. 0 0
      public/icons/Phone.png
  41. 0 0
      public/icons/Play.png
  42. 0 0
      public/icons/Plus.png
  43. 0 0
      public/icons/Save.png
  44. 0 0
      public/icons/Saw.png
  45. 0 0
      public/icons/Search.png
  46. 0 0
      public/icons/ThreeDots.png
  47. 0 0
      public/icons/Trash.png
  48. 0 0
      public/icons/Wrong.png
  49. 0 0
      public/icons/Wrong2.png
  50. 0 25
      src/App.jsx
  51. 65 0
      src/App.vue
  52. 0 157
      src/Components/DesktopSidebar.jsx
  53. 0 109
      src/Components/MobileSidebar.jsx
  54. 0 119
      src/Components/Player.jsx
  55. 0 13
      src/Components/ProfileVideo.jsx
  56. 0 29
      src/Components/Sidebar.jsx
  57. 0 67
      src/Components/VideoFeed.jsx
  58. 0 51
      src/Components/VideoSearchResult.jsx
  59. 0 55
      src/Login.jsx
  60. 0 78
      src/Profile.jsx
  61. 0 80
      src/Search.jsx
  62. 266 0
      src/components/DesktopSidebar.vue
  63. 142 0
      src/components/MobileSidebar.vue
  64. 275 0
      src/components/Player.vue
  65. 59 0
      src/components/ProfileVideo.vue
  66. 31 0
      src/components/Sidebar.vue
  67. 15 0
      src/components/VideoFeed.vue
  68. 175 0
      src/components/VideoSearchResult.vue
  69. 16 0
      src/components/icons/ArrowDown.vue
  70. 16 0
      src/components/icons/ArrowLeft.vue
  71. 16 0
      src/components/icons/ArrowRight.vue
  72. 16 0
      src/components/icons/ArrowTopLeft.vue
  73. 16 0
      src/components/icons/ArrowTopRight.vue
  74. 16 0
      src/components/icons/ArrowUp.vue
  75. 16 0
      src/components/icons/Checkmark.vue
  76. 16 0
      src/components/icons/Checkmark2.vue
  77. 16 0
      src/components/icons/Compass.vue
  78. 16 0
      src/components/icons/Contact.vue
  79. 16 0
      src/components/icons/Deodorant.vue
  80. 16 0
      src/components/icons/Edit.vue
  81. 16 0
      src/components/icons/Gear.vue
  82. 16 0
      src/components/icons/Grandpa.vue
  83. 16 0
      src/components/icons/Heart.vue
  84. 16 0
      src/components/icons/Home.vue
  85. 16 0
      src/components/icons/Knife.vue
  86. 16 0
      src/components/icons/Minus.vue
  87. 16 0
      src/components/icons/Pause.vue
  88. 16 0
      src/components/icons/Person.vue
  89. 16 0
      src/components/icons/Phone.vue
  90. 16 0
      src/components/icons/Play.vue
  91. 16 0
      src/components/icons/Plus.vue
  92. 16 0
      src/components/icons/Save.vue
  93. 16 0
      src/components/icons/Saw.vue
  94. 16 0
      src/components/icons/Search.vue
  95. 16 0
      src/components/icons/ThreeDots.vue
  96. 16 0
      src/components/icons/Trash.vue
  97. 16 0
      src/components/icons/Wrong.vue
  98. 16 0
      src/components/icons/Wrong2.vue
  99. 16 0
      src/components/icons/old icon.vue
  100. 0 24
      src/css/App.css

+ 9 - 0
.editorconfig

@@ -0,0 +1,9 @@
+[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue,css,scss,sass,less,styl}]
+charset = utf-8
+indent_size = 2
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+end_of_line = lf
+max_line_length = 100

+ 0 - 1
.env

@@ -1 +0,0 @@
-SERVER_URL="http://localhost:8080"

+ 1 - 0
.gitattributes

@@ -0,0 +1 @@
+* text=auto eol=lf

+ 7 - 1
.gitignore

@@ -8,17 +8,23 @@ pnpm-debug.log*
 lerna-debug.log*
 
 node_modules
+.DS_Store
 dist
 dist-ssr
+coverage
 *.local
 
+/cypress/videos/
+/cypress/screenshots/
+
 # Editor directories and files
 .vscode/*
 !.vscode/extensions.json
 .idea
-.DS_Store
 *.suo
 *.ntvs*
 *.njsproj
 *.sln
 *.sw?
+
+*.tsbuildinfo

+ 7 - 0
.prettierrc.json

@@ -0,0 +1,7 @@
+{
+  "$schema": "https://json.schemastore.org/prettierrc",
+  "semi": false,
+  "singleQuote": true,
+  "tabWidth": 4,
+  "printWidth": 100
+}

+ 8 - 0
.vscode/extensions.json

@@ -0,0 +1,8 @@
+{
+  "recommendations": [
+    "Vue.volar",
+    "dbaeumer.vscode-eslint",
+    "EditorConfig.EditorConfig",
+    "esbenp.prettier-vscode"
+  ]
+}

+ 30 - 7
README.md

@@ -1,12 +1,35 @@
-# React + Vite
+# hajeebtok-frontend
 
-This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
+This template should help get you started developing with Vue 3 in Vite.
 
-Currently, two official plugins are available:
+## Recommended IDE Setup
 
-- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
-- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
 
-## Expanding the ESLint configuration
+## Customize configuration
 
-If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.
+See [Vite Configuration Reference](https://vite.dev/config/).
+
+## Project Setup
+
+```sh
+npm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+npm run dev
+```
+
+### Compile and Minify for Production
+
+```sh
+npm run build
+```
+
+### Lint with [ESLint](https://eslint.org/)
+
+```sh
+npm run lint
+```

+ 0 - 33
eslint.config.js

@@ -1,33 +0,0 @@
-import js from '@eslint/js'
-import globals from 'globals'
-import reactHooks from 'eslint-plugin-react-hooks'
-import reactRefresh from 'eslint-plugin-react-refresh'
-
-export default [
-  { ignores: ['dist'] },
-  {
-    files: ['**/*.{js,jsx}'],
-    languageOptions: {
-      ecmaVersion: 2020,
-      globals: globals.browser,
-      parserOptions: {
-        ecmaVersion: 'latest',
-        ecmaFeatures: { jsx: true },
-        sourceType: 'module',
-      },
-    },
-    plugins: {
-      'react-hooks': reactHooks,
-      'react-refresh': reactRefresh,
-    },
-    rules: {
-      ...js.configs.recommended.rules,
-      ...reactHooks.configs.recommended.rules,
-      'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
-      'react-refresh/only-export-components': [
-        'warn',
-        { allowConstantExport: true },
-      ],
-    },
-  },
-]

+ 13 - 23
index.html

@@ -1,23 +1,13 @@
-<!doctype html>
-<html lang="en">
-
-<head>
-    <meta charset="UTF-8" />
-    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>HajeebTok</title>
-</head>
-
-<body>
-    <style>
-        html,
-        body {
-            margin: 0;
-        }
-    </style>
-
-    <div id="root"></div>
-    <script type="module" src="/src/main.jsx"></script>
-</body>
-
-</html>
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <meta charset="UTF-8">
+    <link rel="icon" href="/favicon.ico">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Vite App</title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script type="module" src="/src/main.js"></script>
+  </body>
+</html>

+ 8 - 0
jsconfig.json

@@ -0,0 +1,8 @@
+{
+  "compilerOptions": {
+    "paths": {
+      "@/*": ["./src/*"]
+    }
+  },
+  "exclude": ["node_modules", "dist"]
+}

File diff suppressed because it is too large
+ 432 - 166
package-lock.json


+ 16 - 17
package.json

@@ -1,31 +1,30 @@
 {
-  "name": "hajeebtok",
-  "private": true,
+  "name": "hajeebtok-frontend",
   "version": "0.0.0",
+  "private": true,
   "type": "module",
   "scripts": {
     "dev": "vite",
     "build": "vite build",
-    "lint": "eslint .",
-    "preview": "vite preview"
+    "preview": "vite preview",
+    "lint": "eslint . --fix",
+    "format": "prettier --write src/"
   },
   "dependencies": {
     "animejs": "^4.0.2",
-    "axios": "^1.9.0",
+    "axios": "^1.10.0",
     "js-cookie": "^3.0.5",
-    "react": "^19.1.0",
-    "react-dom": "^19.1.0",
-    "react-router": "^7.6.2"
+    "vue": "^3.5.17",
+    "vue-router": "^4.5.1"
   },
   "devDependencies": {
-    "@eslint/js": "^9.25.0",
-    "@types/react": "^19.1.2",
-    "@types/react-dom": "^19.1.2",
-    "@vitejs/plugin-react": "^4.4.1",
-    "eslint": "^9.25.0",
-    "eslint-plugin-react-hooks": "^5.2.0",
-    "eslint-plugin-react-refresh": "^0.4.19",
-    "globals": "^16.0.0",
-    "vite": "^6.3.5"
+    "@eslint/js": "^9.29.0",
+    "@vitejs/plugin-vue": "^6.0.0",
+    "@vue/eslint-config-prettier": "^10.2.0",
+    "eslint-plugin-vue": "~10.2.0",
+    "globals": "^16.2.0",
+    "prettier": "3.5.3",
+    "vite": "^7.0.0",
+    "vite-plugin-vue-devtools": "^7.7.7"
   }
 }

BIN
public/assets/16_final.mp4


BIN
public/assets/34_final.mp4


BIN
public/assets/7_final.mp4


+ 0 - 0
src/assets/banner.png → public/assets/banner.png


+ 0 - 0
src/assets/hajeebtok.png → public/assets/hajeebtok.png


+ 0 - 0
src/assets/logo.png → public/assets/logo.png


BIN
public/favicon.ico


+ 0 - 0
public/icons/arrowDown.png → public/icons/ArrowDown.png


+ 0 - 0
public/icons/arrowLeft.png → public/icons/ArrowLeft.png


+ 0 - 0
public/icons/arrowRight.png → public/icons/ArrowRight.png


+ 0 - 0
public/icons/arrowTopLeft.png → public/icons/ArrowTopLeft.png


+ 0 - 0
public/icons/arrowTopRight.png → public/icons/ArrowTopRight.png


+ 0 - 0
public/icons/arrowUp.png → public/icons/ArrowUp.png


+ 0 - 0
public/icons/checkmark.png → public/icons/Checkmark.png


+ 0 - 0
public/icons/checkmark2.png → public/icons/Checkmark2.png


+ 0 - 0
public/icons/compass.png → public/icons/Compass.png


+ 0 - 0
public/icons/contact.png → public/icons/Contact.png


+ 0 - 0
public/icons/deodorant.png → public/icons/Deodorant.png


+ 0 - 0
public/icons/edit.png → public/icons/Edit.png


+ 0 - 0
public/icons/gear.png → public/icons/Gear.png


+ 0 - 0
public/icons/grandpa.png → public/icons/Grandpa.png


+ 0 - 0
public/icons/heart.png → public/icons/Heart.png


+ 0 - 0
public/icons/home.png → public/icons/Home.png


+ 0 - 0
public/icons/knife.png → public/icons/Knife.png


+ 0 - 0
public/icons/minus.png → public/icons/Minus.png


+ 0 - 0
public/icons/pause.png → public/icons/Pause.png


+ 0 - 0
public/icons/person.png → public/icons/Person.png


+ 0 - 0
public/icons/phone.png → public/icons/Phone.png


+ 0 - 0
public/icons/play.png → public/icons/Play.png


+ 0 - 0
public/icons/plus.png → public/icons/Plus.png


+ 0 - 0
public/icons/save.png → public/icons/Save.png


+ 0 - 0
public/icons/saw.png → public/icons/Saw.png


+ 0 - 0
public/icons/search.png → public/icons/Search.png


+ 0 - 0
public/icons/threeDots.png → public/icons/ThreeDots.png


+ 0 - 0
public/icons/trash.png → public/icons/Trash.png


+ 0 - 0
public/icons/wrong.png → public/icons/Wrong.png


+ 0 - 0
public/icons/wrong2.png → public/icons/Wrong2.png


+ 0 - 25
src/App.jsx

@@ -1,25 +0,0 @@
-import './css/App.css'
-import Sidebar from "./Components/Sidebar"
-import VideoFeed from './Components/VideoFeed'
-import Player from './Components/Player'
-
-function App() {
-  return (
-    <div className="main">
-      <Sidebar />
-      <Player className="top-video" video={1} information={{
-        title: "habibi habibi",
-        description: "my name is john clapper. i clap everyone. i clap first at the cinema. no one else claps.",
-        likes: "1.2M",
-        dislikes: "1K",
-        comments: "1.1K",
-        shares: "392",
-        author: "John Clapper",
-        authorAvatar: "https://i.imgur.com/4Z2b7aH.png",
-        authorId: "johnclapper",
-      }} />
-    </div>
-  )
-}
-
-export default App

+ 65 - 0
src/App.vue

@@ -0,0 +1,65 @@
+<script setup>
+import { RouterView } from 'vue-router'
+</script>
+
+<template>
+    <RouterView />
+</template>
+
+<style>
+@import url('https://fonts.googleapis.com/css2?family=Knewave&family=Pinyon+Script&display=swap');
+
+.title-regular {
+    font-family: 'Pinyon Script', cursive;
+    font-weight: 400;
+    font-style: normal;
+}
+
+.body-regular {
+    font-family: 'Knewave', system-ui;
+    font-weight: 400;
+    font-style: normal;
+}
+
+:root {
+    --accent-color: rgb(255, 0, 234);
+    --background-color: #0e0e0e;
+    --secondary-background-color: #363636;
+    --text-color: white;
+    --inverted-text-color: black;
+    --mobile-width: 768px;
+
+    font-family: 'Knewave', 'Times New Roman', Times, serif;
+    color-scheme: light dark;
+    color: var(--text-color);
+    background-color: var(--background-color);
+
+    width: 100vw;
+    height: 100vh;
+
+    overflow: hidden;
+}
+
+html,
+body {
+    margin: 0;
+}
+
+.main {
+    width: 100vw;
+    height: 100vh;
+    margin: 0;
+    display: flex;
+    flex-direction: row;
+}
+
+@media only screen and (max-width: 768px) {
+    .main {
+        width: 100vw;
+        height: 100vh;
+        margin: 0;
+        display: flex;
+        flex-direction: column;
+    }
+}
+</style>

+ 0 - 157
src/Components/DesktopSidebar.jsx

@@ -1,157 +0,0 @@
-import '../css/DesktopSidebar.css'
-import logo from '../assets/hajeebtok.png'
-import tiny_logo from '../assets/logo.png'
-
-import Home from "../icons/Home.jsx"
-import Compass from "../icons/Compass.jsx"
-import Grandpa from "../icons/Grandpa.jsx"
-import Person from "../icons/Person.jsx"
-import Phone from "../icons/Phone.jsx"
-import Search from "../icons/SearchIcon.jsx"
-import Wrong2 from "../icons/Wrong2.jsx"
-
-import Cookies from "js-cookie"
-import { config, signedIn } from '../main.jsx'
-import { useNavigate } from 'react-router'
-
-function search(minimized, navigate) {
-
-    if (minimized) {
-        navigate("/search");
-        return;
-    }
-
-    // goto search page with search query
-    navigate("/search"); // todo make it take the search query
-}
-
-function HajeeberButton(props) {
-    const {size, minimized, navigate} = props;
-
-    if(signedIn()) {
-        return <>
-            <button onClick={() => {
-                if (signedIn()) {
-                    navigate("/profile/myself");
-                } else {
-                    navigate("/login");
-                }
-            }}>
-                <img src={`${config.serverURL + "/account/myself/picture"}`} width={size} height={size}></img>
-                {!minimized && 'my hajeeber'}
-            </button>
-        </>
-    } else {
-        return <>
-            <button onClick={() => {
-                if(signedIn()) {
-                    navigate("/profile");
-                } else {
-                    navigate("/login");
-                }
-            }}>
-                <Person size={size} />
-                {!minimized && 'my hajeeber'}
-            </button>
-        </>
-    }
-}
-
-function LogOutButton(props) {
-    const { size, minimized } = props;
-
-    if (signedIn()) {
-        return <>
-            <li>
-                <button onClick={logOut}>
-                    <Wrong2 size={size} />
-                    {!minimized && 'log out'}
-                </button>
-            </li>
-        </> 
-    } else {
-        return
-    }
-}
-
-function logOut() {
-    Cookies.remove("token");
-    window.location.reload();
-}
-
-function DesktopSidebar(props) {
-    const minimized = props.minimized;
-    let navigate = useNavigate();
-
-    let size = 40;
-    let sidebarCode = <>
-        <div
-            className="sidebar"
-            style={{ minWidth: minimized ? "150px" : "350px" }}
-        >
-            <div className="top">
-                <img src={minimized ? tiny_logo : logo} style={{ width: minimized ? "100px" : "250px" }} alt="logo" />
-            </div>
-
-            <ul className="middle">
-                <div className="searchContainer" style={{ width: minimized ? "100px" : "250px" }}>
-                    <button className="searchButton" onClick={() => {search(minimized, navigate)}}>
-                        <Search size={size} />
-                    </button>
-                    {!minimized && <input type="text" placeholder="Search" className="searchBar" />}
-                </div>
-
-                <li>
-                    <button onClick={() => {
-                        navigate("/");
-                    }}>
-                        <Home size={size} />
-                        {!minimized && 'home'}
-                    </button>
-                </li>
-
-                <li>
-                    <button>
-                        <Compass size={size} />
-                        {!minimized && 'explore'}
-                    </button>
-                </li>
-
-                <li>
-                    <button>
-                        <Grandpa size={size} />
-                        {!minimized && 'following'}
-                    </button>
-                </li>
-
-                <li>
-                    <button>
-                        <Person size={size} />
-                        {!minimized && 'friends'}
-                    </button>
-                </li>
-
-                <li>
-                    <HajeeberButton size={size} minimized={minimized} navigate={navigate} />
-                </li>
-
-                <LogOutButton size={size} minimized={minimized} />
-
-                <li>
-                    <button>
-                        <Phone size={size} />
-                        {!minimized && 'contact'}
-                    </button>
-                </li>
-            </ul>
-
-            <div className="bottom">
-                <p>{!minimized && 'developer by buttplugstudios.xyz'}</p>
-            </div>
-        </div>
-    </>
-
-    return sidebarCode;
-}
-
-export default DesktopSidebar

+ 0 - 109
src/Components/MobileSidebar.jsx

@@ -1,109 +0,0 @@
-import '../css/MobileSidebar.css'
-
-import Home from "../icons/Home.jsx"
-import Person from "../icons/Person.jsx"
-import Search from "../icons/SearchIcon.jsx"
-
-import Cookies from "js-cookie"
-import { config, signedIn } from "../main.jsx"
-import Wrong2 from '../icons/Wrong2.jsx'
-import { useNavigate } from 'react-router'
-
-function HajeeberButton(props) {
-	const {size, navigate} = props;
-
-	if (signedIn()) {
-		return <>
-			<button onClick={() => {
-				if (signedIn()) {
-					navigate("/profile");
-				} else {
-					navigate("/login");
-				}
-			}}>
-				<img src={`${config.serverURL + "/account/myself/picture"}`} width={size} height={size}></img>
-				hajeeber
-			</button>
-		</>
-	} else {
-		return <>
-			<button onClick={() => {
-				if (signedIn()) {
-					navigate("/profile/myself");
-				} else {
-					navigate("/login");
-				}
-			}}>
-				<Person size={size} />
-				hajeeber
-			</button>
-		</>
-	}
-}
-
-function LogOutButton(props) {
-	const size = props.size;
-
-	if(signedIn()) {
-		return <>
-			<li>
-				<button onClick={logOut}>
-					<Wrong2 size={size} />
-					log out
-				</button>
-			</li>
-		</>
-	} else {
-		return
-	}
-}
-
-function logOut() {
-	Cookies.remove("token");
-	window.location.reload();
-}
-
-function MobileSidebar() {
-	let size = 40;
-	let navigate = useNavigate();
-
-	return (
-		<>
-			<div className="sidebar-container">
-				<ul className="mobile-sidebar">
-					<li>
-						<button onClick={() => {
-							navigate("/");
-						}}>
-							<Home size={size} />
-							home
-						</button>
-					</li>
-
-					<li>
-						<button>
-							<Search size={size} />
-							search
-						</button>
-					</li>
-
-					<li>
-						<button>
-							<Person size={size} />
-							friends
-						</button>
-					</li>
-
-					<li>
-						<HajeeberButton size={size} navigate={navigate} />
-					</li>
-
-					<LogOutButton size={size} />
-				</ul>
-			</div>
-		</>
-	)
-}
-
-
-export default MobileSidebar

+ 0 - 119
src/Components/Player.jsx

@@ -1,119 +0,0 @@
-import '../css/Player.css'
-
-import Heart from "../icons/Heart.jsx"
-import Deodorant from "../icons/Deodorant.jsx"
-import Contact from "../icons/Contact.jsx"
-import ArrowRight from "../icons/ArrowRight.jsx"
-import ThreeDots from "../icons/ThreeDots.jsx"
-import Play from "../icons/Play.jsx"
-import Pause from "../icons/Pause.jsx"
-import { default as axios } from 'axios'
-import { config } from '../main.jsx'
-import { animate, createScope } from 'animejs'
-import { useRef, useEffect } from 'react';
-
-function Player(props) {
-    const root = useRef(null);
-    const scope = useRef(null);
-    const { video, information, top, className } = props;
-    const screenHeight = window.innerHeight;
-    const videoHeight = screenHeight - 100; // Adjusting for some padding/margin
-    const videoRef = useRef(null);
-
-    const animateDetail = (id) => {
-        scope.current = createScope({ root }).add(() => {
-            console.log("monkey")
-            animate(id, {
-                width: {
-                    from: "50px",
-                    to: "300px"
-                },
-                height: {
-                    from: "50px",
-                    to: "300px"
-                },
-                opacity: {
-                    from: 0,
-                    to: 0.5
-                },
-
-                ease: "inExpo",
-                duration: 500,
-                loop: false,
-                onComplete: () => {
-                    animate(id, {
-                        opacity: {
-                            from: 0.5,
-                            to: 0
-                        }
-                    })
-                }
-            });
-        })
-    }
-
-    const handlePlay = () => {
-        if(videoRef.current.paused) {
-            videoRef.current.play();
-            animateDetail("#play-icon");
-        } else {
-            videoRef.current.pause();
-            animateDetail("#pause-icon");
-        }
-    }
-
-    return (
-        <>
-            <div className={`container ${className}`} ref={root} style={{ transform: `translateY(${top})` }}>
-                <div className="video-container" onClick={handlePlay}>
-                    <video
-                        className="video-player"
-                        id="video-player"
-                        height={videoHeight}
-                        ref={videoRef}
-                    >
-                        <source src={config.serverURL + "/video/" + video} type="video/mp4"></source>
-                    </video>
-
-                    <div className="animated-detail" id="play-icon">
-                        <Play size={"100%"} />
-                    </div>
-
-                    <div className="animated-detail" id="pause-icon">
-                        <Pause size={"100%"} />
-                    </div>
-
-                    <div className="video-information">
-                        <h1>{information.title}</h1>
-                        <p>{information.description}</p>
-                    </div>
-                </div>
-
-                <div className="video-interactions">
-                    <button className="interaction" id="like">
-                        <Heart size={30} />
-                        <span className="interaction-count">{information.likes}</span>
-                    </button>
-                    <button className="interaction" id="dislike">
-                        <Deodorant size={30} />
-                        <span className="interaction-count">{information.dislikes}</span>
-                    </button>
-                    <button className="interaction" id="comment">
-                        <Contact size={30} />
-                        <span className="interaction-count">{information.comments}</span>
-                    </button>
-                    <button className="interaction" id="share">
-                        <ArrowRight size={30} />
-                        <span className="interaction-count">{information.shares}</span>
-                    </button>
-                    <button className="interaction" id="more">
-                        <ThreeDots size={30} />
-                        <span className="interaction-count">More</span>
-                    </button>
-                </div>
-            </div>
-        </>
-    );
-}
-
-export default Player

+ 0 - 13
src/Components/ProfileVideo.jsx

@@ -1,13 +0,0 @@
-import "../css/ProfileVideo.css";
-import { config } from "../main";
-
-function ProfileVideo(props) {
-	const { id } = props;
-	return (
-		<div className="profile-video">
-			<img src={`${config.serverURL}/video/${id}/thumbnail`} className="profile-video-thumbnail"></img>
-		</div>
-	)
-}
-
-export default ProfileVideo

+ 0 - 29
src/Components/Sidebar.jsx

@@ -1,29 +0,0 @@
-import DesktopSidebar from './DesktopSidebar.jsx'
-import MobileSidebar from './MobileSidebar'
-import { useState, useEffect } from 'react'
-
-function Sidebar() {
-	const [minimized, setMinimized] = useState(window.innerWidth < 1300)
-	const [isMobile, setIsMobile] = useState(window.innerWidth < 768)
-
-	useEffect(() => {
-		const handleResize = () => {
-			setMinimized(window.innerWidth < 1300)
-			setIsMobile(window.innerWidth < 768)
-		}
-		window.addEventListener('resize', handleResize)
-		return () => window.removeEventListener('resize', handleResize)
-	}, [])
-
-	return (
-		<>
-			{isMobile ? (
-				<MobileSidebar minimized={minimized} />
-			) : (
-				<DesktopSidebar minimized={minimized} />
-			)}
-		</>
-	)
-}
-
-export default Sidebar

+ 0 - 67
src/Components/VideoFeed.jsx

@@ -1,67 +0,0 @@
-import { useRef, useState } from "react"
-import "../css/VideoFeed.css"
-import Player from "./Player";
-import { animate, createScope } from "animejs";
-
-function VideoFeed() {
-	const {feed, setFeed} = useState(null);
-	const root = useRef(null);
-	const scope = useRef(null);
-
-	const {topState, setTopState} = useState(true);
-	const {bottomState, setBottomState } = useState(false);
-
-	const screenHeight = window.innerHeight;
-	let scrolling = false;
-
-	const stiffness = 550;
-	const damping = 15;
-
-	// Animation functions (no hooks inside)
-	const scrollDown = () => {
-		scope.current = createScope({ root }).add(() => {
-			animate(".bottom-video", {
-				y: [-screenHeight, 0],
-				ease: createSpring({ stiffness, damping }),
-			});
-			animate(".top-video", {
-				y: [0, screenHeight],
-				ease: createSpring({ stiffness, damping }),
-			});
-		});
-	};
-	const scrollUp = () => {
-		scope.current = createScope({ root }).add(() => {
-			animate(".bottom-video", {
-				y: [0, -screenHeight],
-				ease: createSpring({ stiffness, damping }),
-			});
-			animate(".top-video", {
-				y: [-screenHeight, 0],
-				ease: createSpring({ stiffness, damping }),
-			});
-		});
-	};
-
-	useEffect(() => {
-		const handleWheel = (ev) => {
-			if (ev.deltaY > 0) {
-				console.log("scroll up")
-				scrollUp();
-			} else {
-				scrollDown();
-			}
-		};
-		document.addEventListener("wheel", handleWheel);
-		return () => document.removeEventListener("wheel", handleWheel);
-	}, [screenHeight]);
-
-	return (
-		<div ref={root}>
-			<Player id="player1" />
-			<Player id="player2" />
-		</div>
-	)
-}
-
-export default VideoFeed

+ 0 - 51
src/Components/VideoSearchResult.jsx

@@ -1,51 +0,0 @@
-import '../css/SearchResult.css'
-import { config } from "../main";
-
-import Heart from '../icons/Heart';
-import Deodorant from '../icons/Deodorant';
-import Contact from '../icons/Contact';
-import ArrowRight from '../icons/ArrowRight';
-
-function VideoSearchResult(props) {
-	const { id,
-		title,
-		author,
-		likes,
-		dislikes,
-		comments,
-		shares,
-	} = props;
-
-	return (
-		<div className="search-result">
-			<img src={`${config.serverURL}/video/${id}/thumbnail`} className="search-result-thumbnail" />
-			<div className="search-result-details">
-				<h1>{title}</h1>
-				<span className="search-result-author">
-					<img src={`${config.serverURL}/account/${id}/picture`} className="search-result-author-image"></img>
-					<p>{author}</p>
-				</span>
-				<div className="search-result-interactions">
-					<span className="search-result-interaction">
-						<Heart size={30} />
-						<span className="search-result-interaction-count">{likes}</span>
-					</span>
-					<span className="search-result-interaction">
-						<Deodorant size={30} />
-						<span className="search-result-interaction-count">{dislikes}</span>
-					</span>
-					<span className="search-result-interaction">
-						<Contact size={30} />
-						<span className="search-result-interaction-count">{comments}</span>
-					</span>
-					<span className="search-result-interaction">
-						<ArrowRight size={30} />
-						<span className="search-result-interaction-count">{shares}</span>
-					</span>
-				</div>
-			</div>
-		</div>
-	)
-}
-
-export default VideoSearchResult

+ 0 - 55
src/Login.jsx

@@ -1,55 +0,0 @@
-import './css/Login.css'
-import Sidebar from './Components/Sidebar'
-import Cookies from 'js-cookie'
-import banner from "/src/assets/banner.png"
-import { default as axios } from 'axios'
-import { config } from './main'
-import { useNavigate } from 'react-router'
-import React, { useEffect } from 'react'
-
-function Login() {
-	let navigate = useNavigate();
-	if (Cookies.get("token") && Cookies.get("token").startsWith("HajeebToken ")) {
-		useEffect(() => {
-			return navigate("/");
-		}, [])
-	}
-
-	const handleSubmit = async (e) => {
-		e.preventDefault();
-		document.getElementById("submit").disabled = true;
-
-		const formData = new FormData(e.target);
-		let response = await axios.post(config.serverURL + "/account/token", {
-			username: formData.get("username"),
-			password: formData.get("password")
-		})
-
-		if(response.data.error) { // Login unsuccessful
-			document.getElementById("submit").disabled = false;
-			return alert(`Login error: ${response.data.message}`);
-		}
-
-		// Login successful
-		Cookies.set("token", `HajeebToken ${response.data.token}`);
-		return navigate("/profile/myself");
-	};
-
-	return (
-		<>
-			<div className="main">
-				<Sidebar />
-				<div className="login-container">
-					<form className="login" id="form" onSubmit={handleSubmit}>
-						<img src={banner} width="300px"></img>
-						<input type="text" placeholder="username" name="username"></input>
-						<input type="password" placeholder="password" name="password"></input>
-						<input type="submit" value="Log in/Sign up/Register/Enter Website" id="submit"></input>
-					</form>
-				</div>
-			</div>
-		</>
-	)
-}
-
-export default Login

+ 0 - 78
src/Profile.jsx

@@ -1,78 +0,0 @@
-import './css/Profile.css'
-import Sidebar from './Components/Sidebar'
-import { default as axios } from 'axios'
-import { config } from './main'
-import { useParams } from 'react-router'
-import { useEffect, useState } from 'react'
-import ProfileVideo from './Components/ProfileVideo'
-
-function Profile() {
-	const params = useParams();
-	const [data, setData] = useState(null);
-
-	useEffect(() => {
-		let ignore = false;
-		setData(null);
-		axios.get(`${config.serverURL}/account/${params.id}/get`, {
-			withCredentials: true
-		}).then(response => {
-			if (response.error) setData({
-				username: "profile not found"
-			});
-			if(!ignore) setData(response.data);
-
-			console.log(response.data);
-		}).catch(error => {
-			setData({
-				username: "profile not found",
-				followers: "profile not found",
-				following: "profile not found",
-			});
-		});
-		
-		return () => {
-			ignore = true;
-		}
-	}, [params, config]);
-
-
-
-	return (
-		<>
-			<div className="main">
-				<Sidebar />
-				<div className="profile-container">
-					<div className="profile-details">
-						<span className="profile-detail" id="profile-picture">
-							<img src={`${config.serverURL}/account/${params.id}/picture`} className="profile-picture" alt="profile" />
-							{data ? data.username : "loading"}
-						</span>
-
-						<span className="profile-detail">
-							{data ? data.followers : "loading"} <br />
-							followers
-						</span>
-
-						<span className="profile-detail">
-							{data ? data.following : "loading"} <br />
-							following
-						</span>
-
-						<span className="profile-detail" id="profile-video-detail">
-							2 <br />
-							videos
-						</span>
-					</div>
-
-					<div className="profile-videos">
-						<ProfileVideo id={1} />
-						<ProfileVideo id={1} />
-						<ProfileVideo id={1} />
-					</div>
-				</div>
-			</div>
-		</>
-	)
-}
-
-export default Profile

+ 0 - 80
src/Search.jsx

@@ -1,80 +0,0 @@
-import './css/Search.css'
-import Sidebar from './Components/Sidebar'
-import { default as axios } from 'axios'
-import Cookies from 'js-cookie'
-import SearchIcon from './icons/SearchIcon'
-import VideoSearchResult from './Components/VideoSearchResult'
-import { config } from './main'
-import React, { useRef } from 'react'
-import { createRoot } from 'react-dom/client';
-
-let searchResults;
-let searched;
-let searchResultsRef;
-let searchStatusRef;
-
-async function search2() {
-	const searchBar = document.getElementById("search-bar");
-	if(searchBar.value.trim() != "") {
-		if(!searched) searchResults = createRoot(searchResultsRef.current);
-		if(searched) { searchResults.unmount(); searchResults = createRoot(searchResultsRef.current); }
-		searched = true;
-
-		searchStatusRef.current.innerText = "searching!!";
-		const response = await axios.post(`${config.serverURL}/video/search`, {
-			"query": searchBar.value
-		})
-
-		if(!response.error) {
-			if(response.data.length === 0) {
-				return searchStatusRef.current.innerText = "no results :(";
-			}
-
-			response.data.forEach(video => {
-				console.log(video)
-				searchResults.render(<VideoSearchResult 
-					id={video.id}
-					title={video.title}
-					author={video.author.username}
-					likes={video.likes}
-					dislikes={video.dislikes}
-					comments={video.comments}
-					shares={video.shares}
-				/>)
-			})
-		} else {
-			searchStatusRef.current.innerText = `search error: ${response.error}`;
-		}
-	} else {
-		searchStatusRef.current.innerText = `no`;
-	}
-}
-
-function Search() {
-	searchResultsRef = useRef(null);
-	searchStatusRef = useRef(null);
-
-	return (
-		<>
-			<div className="main">
-				<Sidebar />
-				<div className="search-container">
-					<div className="search-bar-container">
-						<button className="search-button" onClick={() => {search2(searchResults)}}>
-							<SearchIcon size={50} />
-						</button>
-						<input type="text" placeholder="Search" className="search-bar" id="search-bar" />
-					</div>
-
-					<div className="search-results" id="search-results" ref={searchResultsRef}>
-						<div className="search-status" ref={searchStatusRef}>
-							
-						</div>
-					</div>
-				</div>
-			</div>
-		</>
-	)
-}
-
-export default Search

+ 266 - 0
src/components/DesktopSidebar.vue

@@ -0,0 +1,266 @@
+<script>
+import { defineComponent } from 'vue'
+import Cookies from 'js-cookie'
+import { useRouter } from 'vue-router'
+import { config } from '@/main.js'
+
+// icon imports
+import Search from '@/components/icons/Search.vue'
+import Home from '@/components/icons/Home.vue'
+import Compass from '@/components/icons/Compass.vue'
+import Grandpa from '@/components/icons/Grandpa.vue'
+import Person from '@/components/icons/Person.vue'
+import Phone from '@/components/icons/Phone.vue'
+import Wrong2 from '@/components/icons/Wrong2.vue'
+
+export default defineComponent({
+    name: 'DesktopSidebar',
+    setup() {
+        const router = useRouter()
+        return { router }
+    },
+    methods: {
+        signedIn() {
+            return Cookies.get('token') && Cookies.get('token').startsWith('HajeebToken')
+        },
+        logOut() {
+            Cookies.remove('token')
+            window.location.reload()
+        },
+        search() {
+            if (this.minimized) return this.router.push('/search')
+
+            const searchQuery = document.getElementById('search-query')
+            if (searchQuery.value.trim() === '') return this.router.push('/search')
+            return this.router.push({
+                name: 'search',
+                params: { searchQuery: searchQuery.value.trim() },
+            });
+        },
+    },
+    data() {
+        return {
+            config,
+            size: 40,
+        }
+    },
+    props: {
+        minimized: {
+            type: Boolean,
+            required: true,
+        },
+    },
+    components: { Search, Home, Compass, Grandpa, Person, Phone, Wrong2 },
+})
+</script>
+
+<template>
+    <div class="sidebar" :style="{ minWidth: minimized ? '150px' : '350px' }">
+        <div class="top">
+            <img
+                :src="minimized ? '/assets/logo.png' : '/assets/banner.png'"
+                :style="{ width: minimized ? '100px' : '250px' }"
+                alt="logo"
+            />
+        </div>
+
+        <ul class="middle">
+            <div class="searchContainer" :style="{ width: minimized ? '100px' : '250px' }">
+                <button class="searchButton" @click="search">
+                    <Search :size="size" />
+                </button>
+                <input
+                    v-if="!minimized"
+                    type="text"
+                    placeholder="Search"
+                    class="searchBar"
+                    id="search-query"
+                />
+            </div>
+
+            <li>
+                <button @click="this.router.push('/')">
+                    <Home :size="size" />
+                    <span v-if="!minimized">home</span>
+                </button>
+            </li>
+
+            <li>
+                <button>
+                    <Compass :size="size" />
+                    <span v-if="!minimized">explore</span>
+                </button>
+            </li>
+
+            <li>
+                <button>
+                    <Grandpa :size="size" />
+                    <span v-if="!minimized">following</span>
+                </button>
+            </li>
+
+            <li>
+                <button>
+                    <Person :size="size" />
+                    <span v-if="!minimized">friends</span>
+                </button>
+            </li>
+
+            <li>
+                <button v-if="signedIn()" @click="this.router.push('/profile/myself')">
+                    <img
+                        :src="`${config.serverURL}/account/myself/picture`"
+                        :width="size"
+                        :height="size"
+                        alt="profile picture"
+                    />
+                    <span v-if="!minimized">my hajeeber</span>
+                </button>
+
+                <button v-else @click="this.router.push('/login')">
+                    <img
+                        :src="`${config.serverURL}/account/getPremiumProfilePicture/18`"
+                        :width="size"
+                        :height="size"
+                        alt="profile picture"
+                    />
+                    <span v-if="!minimized">my hajeeber</span>
+                </button>
+            </li>
+
+            <li v-if="signedIn()">
+                <button @click="logOut">
+                    <Wrong2 :size="size" />
+                    <span v-if="!minimized">log out</span>
+                </button>
+            </li>
+
+            <li>
+                <button>
+                    <Phone :size="size" />
+                    <span v-if="!minimized">contact</span>
+                </button>
+            </li>
+        </ul>
+
+        <div class="bottom">
+            <p v-if="!minimized">developer by buttplugstudios.xyz</p>
+        </div>
+    </div>
+</template>
+
+<style scoped>
+.sidebar {
+    height: 100vh;
+    margin: 0;
+    padding: 0;
+
+    background-color: var(--secondary-background-color);
+    color: var(--text-color);
+
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+
+    top: 0;
+    left: 0;
+    z-index: 3;
+}
+
+li {
+    text-decoration: none;
+    list-style: none;
+}
+
+.sidebar li button {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+
+    padding: 10px 10px;
+    background: none;
+    color: var(--accent-color);
+    font-family: 'Pinyon Script', cursive;
+    font-size: 30px;
+
+    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;
+}
+
+.sidebar li button:hover {
+    color: black;
+    cursor: pointer;
+}
+
+.top {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.bottom {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+
+    font-family: 'Knewave', system-ui;
+    font-size: 20px;
+}
+
+.searchButton {
+    background-color: transparent;
+    border: none;
+}
+
+.searchButton:hover {
+    cursor: pointer;
+    animation-name: interaction;
+    animation-duration: 1s;
+    animation-iteration-count: infinite;
+}
+
+.searchContainer {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    gap: 10px;
+
+    background-color: var(--text-color);
+    border-radius: 10px;
+}
+
+.searchBar {
+    padding: 6px;
+    font-size: 20px;
+    width: 150px;
+    background-color: var(--text-color);
+    border: none;
+    color: var(--inverted-text-color);
+    font-family: 'Knewave', system-ui;
+}
+
+.searchBar:focus {
+    outline: none;
+}
+
+@keyframes interaction {
+    0% {
+        transform: scale(1);
+    }
+
+    50% {
+        transform: scale(1.2);
+    }
+
+    100% {
+        transform: scale(1);
+    }
+}
+</style>

+ 142 - 0
src/components/MobileSidebar.vue

@@ -0,0 +1,142 @@
+<script>
+import { defineComponent } from 'vue'
+import {useRouter} from 'vue-router'
+import Cookies from 'js-cookie'
+import { config } from '@/main';
+
+// icon imports
+import Search from '@/components/icons/Search.vue'
+import Home from '@/components/icons/Home.vue'
+import Person from '@/components/icons/Person.vue'
+import Wrong2 from '@/components/icons/Wrong2.vue'
+
+export default defineComponent({
+    name: 'MobileSidebar',
+    setup () {
+        const router = useRouter();
+        return {router};
+    },
+    methods: {
+        signedIn () {
+            return Cookies.get('token') && Cookies.get('token').startsWith('HajeebToken')
+        },
+        logOut () {
+            Cookies.remove("token");
+            window.location.reload();
+        }
+    },
+    data() {
+        return {
+            size: 40,
+            config
+        }
+    },
+    components: {Search, Home, Person, Wrong2}
+})
+</script>
+
+<template>
+    <div class="sidebar-container">
+        <ul class="mobile-sidebar">
+            <li>
+                <button @click="this.router.push('/')">
+                    <Home :size="size" />
+                    home
+                </button>
+            </li>
+
+            <li>
+                <button>
+                    <Search :size="size" />
+                    search
+                </button>
+            </li>
+
+            <li>
+                <button>
+                    <Person :size="size" />
+                    friends
+                </button>
+            </li>
+
+            <li>
+                <button v-if="signedIn()" @click="this.router.push('/profile/myself')">
+                    <img :src="`${config.serverURL}/account/myself/picture`" :width="size" :height="size" alt="profile picture"/>
+                    hajeeber
+                </button>
+                <button v-else @click="this.router.push('/login')">
+                    <img :src="`${config.serverURL}/account/getPremiumProfilePicture/18`" :width="size" :height="size" alt="profile picture" />
+                    hajeeber
+                </button>
+            </li>
+
+            <li v-if="signedIn()">
+                <button @click="logOut()">
+                    <Wrong2 :size="size" />
+                    log out
+                </button>
+            </li>
+        </ul>
+    </div>
+</template>
+
+<style scoped>
+.sidebar-container {
+    height: 100px;
+    width: 100vw;
+    margin: 0;
+
+    flex: 1 1 0;
+
+    display: flex;
+    align-items: flex-end;
+
+    pointer-events: none;
+    position: fixed;
+    left: 0;
+    bottom: 0;
+}
+
+li {
+    text-decoration: none;
+    list-style: none;
+}
+
+.mobile-sidebar {
+    margin: 0;
+    pointer-events: all;
+    width: 100vw;
+    height: 100px;
+    padding: 0;
+    justify-content: space-between;
+
+    background-color: var(--secondary-background-color);
+    color: var(--text-color);
+
+    display: flex;
+    flex-direction: row;
+    gap: 10px;
+
+    z-index: 3;
+}
+
+
+.mobile-sidebar li button {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+
+    border: none;
+
+    padding: 10px 10px;
+    background: none;
+    color: var(--accent-color);
+    font-family: "Knewave", cursive;
+    font-size: 20px;
+}
+
+.mobile-sidebar li button:hover {
+    color: var(--inverted-text-color);
+    cursor: pointer;
+}
+</style>

+ 275 - 0
src/components/Player.vue

@@ -0,0 +1,275 @@
+<script>
+import { defineComponent } from 'vue'
+import { config } from '@/main.js'
+import { animate } from 'animejs'
+
+// icon imports
+import Heart from '@/components/icons/Heart.vue'
+import Play from '@/components/icons/Play.vue'
+import Pause from '@/components/icons/Pause.vue'
+import Deodorant from '@/components/icons/Deodorant.vue'
+import Contact from '@/components/icons/Contact.vue'
+import ArrowRight from '@/components/icons/ArrowRight.vue'
+import ThreeDots from '@/components/icons/ThreeDots.vue'
+
+export const size = 30
+export const screenHeight = window.innerHeight
+export const videoHeight = screenHeight - 100
+
+export default defineComponent({
+    name: 'Player',
+    props: {
+        className: {
+            type: String,
+            required: false,
+            default: ''
+        },
+        information: {
+            type: Object,
+            required: true,
+        },
+        video: {
+            type: Number,
+            required: true
+        }
+    },
+    data() {
+        return {
+            size,
+            config,
+            screenHeight,
+            videoHeight,
+        }
+    },
+    methods: {
+        handlePlay() {
+            const video = document.getElementById('video-player')
+
+            if (video.paused) {
+                video.play()
+                animateDetail('#play-icon')
+            } else {
+                video.pause()
+                animateDetail('#pause-icon')
+            }
+        }
+    },
+    components: {Play, Pause, Heart, Deodorant, Contact, ArrowRight, ThreeDots},
+})
+
+function animateDetail(id) {
+    console.log('monkey')
+    animate(id, {
+        width: {
+            from: '50px',
+            to: '300px'
+        },
+        height: {
+            from: '50px',
+            to: '300px'
+        },
+        opacity: {
+            from: 0,
+            to: 0.5
+        },
+
+        ease: 'inExpo',
+        duration: 500,
+        loop: false,
+        onComplete: () => {
+            animate(id, {
+                opacity: {
+                    from: 0.5,
+                    to: 0
+                }
+            })
+        }
+    })
+}
+</script>
+
+<template>
+    <div :class="`container ${className}`">
+        <div class="video-container" @click="handlePlay">
+            <video
+                class="video-player"
+                id="video-player"
+                :height="videoHeight"
+            >
+                <source :src="config.serverURL + '/video/' + video" type="video/mp4"></source>
+            </video>
+
+            <div class="animated-detail" id="play-icon">
+                <Play size="100%" />
+            </div>
+
+            <div class="animated-detail" id="pause-icon">
+                <Pause size="100%" />
+            </div>
+
+            <div class="video-information">
+                <h1>{{ information.title }}</h1>
+                <p>{{ information.description }}</p>
+            </div>
+        </div>
+
+        <div class="video-interactions">
+            <button class="interaction" id="like">
+                <Heart :size="size" />
+                <span class="interaction-count">{{ information.likes }}</span>
+            </button>
+            <button class="interaction" id="dislike">
+                <Deodorant :size="size" />
+                <span class="interaction-count">{{ information.dislikes }}</span>
+            </button>
+            <button class="interaction" id="comment">
+                <Contact :size="size" />
+                <span class="interaction-count">{{ information.comments }}</span>
+            </button>
+            <button class="interaction" id="share">
+                <ArrowRight :size="size" />
+                <span class="interaction-count">{{ information.shares }}</span>
+            </button>
+            <button class="interaction" id="more">
+                <ThreeDots :size="size" />
+                <span class="interaction-count">More</span>
+            </button>
+        </div>
+    </div>
+</template>
+
+<style scoped>
+.interaction {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    pointer-events: all;
+
+    width: 60px;
+    height: 60px;
+
+    background-color: transparent;
+    border: none;
+
+    text-shadow: #000 1px 0 10px;
+    font-family: "Pinyon Script", cursive;
+    font-size: 20px;
+}
+
+.interaction:hover {
+    cursor: pointer;
+    animation-name: interaction;
+    animation-duration: 1s;
+    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;
+    justify-content: center;
+    align-items: start;
+    z-index: 2;
+    gap: 10px;
+    pointer-events: none;
+
+    transform: translateX(-35px);
+}
+
+.video-information {
+    width: 100%;
+    pointer-events: none;
+
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: start;
+
+    max-width: 550px;
+
+    background: linear-gradient(0deg, rgba(0, 0, 0, 1) 0%, rgba(255, 255, 255, 0) 100%);
+    border-radius: 15px;
+
+    text-shadow: #000 1px 0 10px;
+    color: var(--text-color);
+
+    position: absolute;
+    z-index: 2;
+}
+
+.video-player {
+    border-radius: 15px;
+    min-width: 300px;
+    max-width: 100%;
+}
+
+.container {
+    width: 100%;
+    height: 100%;
+    margin: 0;
+
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    align-items: center;
+}
+
+@media only screen and (max-width: 768px) {
+    .container {
+        height: calc(100vh - 100px);
+    }
+}
+
+.video-container {
+    display: flex;
+    flex-direction: column;
+
+    justify-content: flex-end;
+    align-items: center;
+
+    transform: translateX(35px);
+}
+
+#like {
+    filter: grayscale(100%);
+}
+
+#dislike {
+    filter: grayscale(100%);
+}
+
+.animated-detail {
+    position: fixed;
+    inset: 0px;
+    width: 50px;
+    height: 50px;
+    max-width: 100vw;
+    max-height: 100dvh;
+    margin: auto;
+
+    z-index: 100;
+    pointer-events: none;
+}
+
+#play-icon {
+    opacity: 0;
+}
+
+#pause-icon {
+    opacity: 0;
+}
+</style>

+ 59 - 0
src/components/ProfileVideo.vue

@@ -0,0 +1,59 @@
+<script lang="ts">
+import { defineComponent } from 'vue'
+import { config } from '@/main'
+
+export default defineComponent({
+    name: 'ProfileVideo',
+    props: {
+        id: {
+            type: Number,
+            required: true
+        }
+    },
+    data () {
+        return {
+            config
+        }
+    }
+})
+</script>
+
+<template>
+    <div class="profile-video">
+        <img :src="`${config.serverURL}/video/${id}/thumbnail`" class="profile-video-thumbnail" />
+    </div>
+</template>
+
+<style scoped>
+.profile-video {
+    border-radius: 15px;
+    border: 2px solid var(--accent-color);
+    width: min-content;
+}
+
+.profile-video:hover {
+    cursor: pointer;
+    animation-name: interaction;
+    animation-duration: 1s;
+    animation-iteration-count: infinite;
+}
+
+.profile-video-thumbnail {
+    border-radius: 15px;
+    width: 200px;
+}
+
+@keyframes interaction {
+    0% {
+        transform: scale(1);
+    }
+
+    50% {
+        transform: scale(1.2);
+    }
+
+    100% {
+        transform: scale(1);
+    }
+}
+</style>

+ 31 - 0
src/components/Sidebar.vue

@@ -0,0 +1,31 @@
+<script>
+import { defineComponent } from 'vue'
+import DesktopSidebar from '@/components/DesktopSidebar.vue'
+import MobileSidebar from '@/components/MobileSidebar.vue'
+
+export default defineComponent({
+    name: 'Sidebar',
+    components: { DesktopSidebar, MobileSidebar },
+    data() {
+        return {
+            windowWidth: window.innerWidth,
+        }
+    },
+    created() {
+        window.addEventListener('resize', this.handleResize)
+    },
+    unmounted() {
+        window.removeEventListener('resize', this.handleResize)
+    },
+    methods: {
+        handleResize() {
+            this.windowWidth = window.innerWidth
+        },
+    },
+})
+</script>
+
+<template>
+    <MobileSidebar v-if="windowWidth < 768" />
+    <DesktopSidebar v-if="windowWidth > 768" :minimized="windowWidth < 1300" />
+</template>

+ 15 - 0
src/components/VideoFeed.vue

@@ -0,0 +1,15 @@
+<script lang="ts">
+import {defineComponent} from 'vue'
+
+export default defineComponent({
+name: "VideoFeed"
+})
+</script>
+
+<template>
+
+</template>
+
+<style scoped>
+
+</style>

+ 175 - 0
src/components/VideoSearchResult.vue

@@ -0,0 +1,175 @@
+<script>
+import { defineComponent } from 'vue'
+import { config } from '@/main.js'
+import Deodorant from '@/components/icons/Deodorant.vue'
+import Heart from '@/components/icons/Heart.vue'
+import Contact from '@/components/icons/Contact.vue'
+import ArrowRight from '@/components/icons/ArrowRight.vue'
+
+export default defineComponent({
+    name: 'VideoSearchResult',
+    data () {
+        return {
+            config,
+            size: 30
+        }
+    },
+    props: {
+        id: {
+            type: Number,
+            required: true
+        },
+        title: {
+            type: String,
+            required: true,
+        },
+        author: {
+            type: String,
+            required: true,
+        },
+        likes: {
+            type: Number,
+            required: true,
+        },
+        dislikes: {
+            type: Number,
+            required: true,
+        },
+        comments: {
+            type: Number,
+            required: true,
+        },
+        shares: {
+            type: Number,
+            required: true,
+        }
+    },
+
+    components: {Heart, Deodorant, Contact, ArrowRight},
+})
+</script>
+
+<template>
+    <div class="search-result">
+        <img :src="`${config.serverURL}/video/${id}/thumbnail`" class="search-result-thumbnail" />
+        <div class="search-result-details">
+            <h1>{{title}}</h1>
+            <span class="search-result-author">
+					<img :src="`${config.serverURL}/account/${id}/picture`" class="search-result-author-image" />
+					<p>{{author}}</p>
+				</span>
+            <div class="search-result-interactions">
+					<span class="search-result-interaction">
+						<Heart :size="size" />
+						<span class="search-result-interaction-count">{{likes}}</span>
+					</span>
+                <span class="search-result-interaction">
+						<Deodorant :size="size" />
+						<span class="search-result-interaction-count">{{dislikes}}</span>
+					</span>
+                <span class="search-result-interaction">
+						<Contact :size="size" />
+						<span class="search-result-interaction-count">{{comments}}</span>
+					</span>
+                <span class="search-result-interaction">
+						<ArrowRight :size="size" />
+						<span class="search-result-interaction-count">{{shares}}</span>
+					</span>
+            </div>
+        </div>
+    </div>
+</template>
+
+<style scoped>
+.search-result {
+    display: flex;
+    flex-direction: row;
+
+    align-items: center;
+    justify-content: center;
+
+    gap: 10px;
+}
+
+.search-result-details {
+    display: flex;
+    flex-direction: column;
+    gap: 0px;
+}
+
+.search-result-thumbnail {
+    height: 150px;
+    border-radius: 5px;
+}
+
+.search-result-thumbnail:hover {
+    cursor: pointer;
+    animation-name: interaction;
+    animation-duration: 1s;
+    animation-iteration-count: infinite;
+}
+
+.search-result-details h1 {
+    line-height: 10px;
+}
+
+.search-result-details h1:hover {
+    cursor: pointer;
+    animation-name: interaction;
+    animation-duration: 1s;
+    animation-iteration-count: infinite;
+
+    color: var(--accent-color);
+}
+
+.search-result-author:hover {
+    cursor: pointer;
+    animation-name: interaction;
+    animation-duration: 1s;
+    animation-iteration-count: infinite;
+
+    color: var(--accent-color);
+}
+
+.search-result-interactions {
+    display: flex;
+    flex-direction: row;
+    gap: 10px;
+}
+
+.search-result-interaction {
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    align-items: center;
+}
+
+.search-result-author-image {
+    width: 40px;
+    height: 40px;
+    border-radius: 100%;
+}
+
+.search-result-author {
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-start;
+    align-items: center;
+
+    gap: 10px;
+}
+
+@keyframes interaction {
+    0% {
+        transform: scale(1);
+    }
+
+    50% {
+        transform: scale(1.1);
+    }
+
+    100% {
+        transform: scale(1);
+    }
+}
+</style>

+ 16 - 0
src/components/icons/ArrowDown.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `ArrowDownIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/ArrowDown.png`" :width="size" :height="size" :alt="`ArrowDown icon`"/>
+</template>

+ 16 - 0
src/components/icons/ArrowLeft.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `ArrowLeftIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/ArrowLeft.png`" :width="size" :height="size" :alt="`ArrowLeft icon`"/>
+</template>

+ 16 - 0
src/components/icons/ArrowRight.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `ArrowRightIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/ArrowRight.png`" :width="size" :height="size" :alt="`ArrowRight icon`"/>
+</template>

+ 16 - 0
src/components/icons/ArrowTopLeft.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `ArrowTopLeftIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/ArrowTopLeft.png`" :width="size" :height="size" :alt="`ArrowTopLeft icon`"/>
+</template>

+ 16 - 0
src/components/icons/ArrowTopRight.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `ArrowTopRightIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/ArrowTopRight.png`" :width="size" :height="size" :alt="`ArrowTopRight icon`"/>
+</template>

+ 16 - 0
src/components/icons/ArrowUp.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `ArrowUpIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/ArrowUp.png`" :width="size" :height="size" :alt="`ArrowUp icon`"/>
+</template>

+ 16 - 0
src/components/icons/Checkmark.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `CheckmarkIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Checkmark.png`" :width="size" :height="size" :alt="`Checkmark icon`"/>
+</template>

+ 16 - 0
src/components/icons/Checkmark2.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `Checkmark2Icon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Checkmark2.png`" :width="size" :height="size" :alt="`Checkmark2 icon`"/>
+</template>

+ 16 - 0
src/components/icons/Compass.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `CompassIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Compass.png`" :width="size" :height="size" :alt="`Compass icon`"/>
+</template>

+ 16 - 0
src/components/icons/Contact.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `ContactIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Contact.png`" :width="size" :height="size" :alt="`Contact icon`"/>
+</template>

+ 16 - 0
src/components/icons/Deodorant.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `DeodorantIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Deodorant.png`" :width="size" :height="size" :alt="`Deodorant icon`"/>
+</template>

+ 16 - 0
src/components/icons/Edit.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `EditIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Edit.png`" :width="size" :height="size" :alt="`Edit icon`"/>
+</template>

+ 16 - 0
src/components/icons/Gear.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `GearIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Gear.png`" :width="size" :height="size" :alt="`Gear icon`"/>
+</template>

+ 16 - 0
src/components/icons/Grandpa.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `GrandpaIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Grandpa.png`" :width="size" :height="size" :alt="`Grandpa icon`"/>
+</template>

+ 16 - 0
src/components/icons/Heart.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `HeartIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Heart.png`" :width="size" :height="size" :alt="`Heart icon`"/>
+</template>

+ 16 - 0
src/components/icons/Home.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `HomeIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Home.png`" :width="size" :height="size" :alt="`Home icon`"/>
+</template>

+ 16 - 0
src/components/icons/Knife.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `KnifeIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Knife.png`" :width="size" :height="size" :alt="`Knife icon`"/>
+</template>

+ 16 - 0
src/components/icons/Minus.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `MinusIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Minus.png`" :width="size" :height="size" :alt="`Minus icon`"/>
+</template>

+ 16 - 0
src/components/icons/Pause.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `PauseIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Pause.png`" :width="size" :height="size" :alt="`Pause icon`"/>
+</template>

+ 16 - 0
src/components/icons/Person.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `PersonIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Person.png`" :width="size" :height="size" :alt="`Person icon`"/>
+</template>

+ 16 - 0
src/components/icons/Phone.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `PhoneIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Phone.png`" :width="size" :height="size" :alt="`Phone icon`"/>
+</template>

+ 16 - 0
src/components/icons/Play.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `PlayIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Play.png`" :width="size" :height="size" :alt="`Play icon`"/>
+</template>

+ 16 - 0
src/components/icons/Plus.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `PlusIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Plus.png`" :width="size" :height="size" :alt="`Plus icon`"/>
+</template>

+ 16 - 0
src/components/icons/Save.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `SaveIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Save.png`" :width="size" :height="size" :alt="`Save icon`"/>
+</template>

+ 16 - 0
src/components/icons/Saw.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `SawIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Saw.png`" :width="size" :height="size" :alt="`Saw icon`"/>
+</template>

+ 16 - 0
src/components/icons/Search.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `SearchIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Search.png`" :width="size" :height="size" :alt="`Search icon`"/>
+</template>

+ 16 - 0
src/components/icons/ThreeDots.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `ThreeDotsIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/ThreeDots.png`" :width="size" :height="size" :alt="`ThreeDots icon`"/>
+</template>

+ 16 - 0
src/components/icons/Trash.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `TrashIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Trash.png`" :width="size" :height="size" :alt="`Trash icon`"/>
+</template>

+ 16 - 0
src/components/icons/Wrong.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `WrongIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Wrong.png`" :width="size" :height="size" :alt="`Wrong icon`"/>
+</template>

+ 16 - 0
src/components/icons/Wrong2.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `Wrong2Icon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/Wrong2.png`" :width="size" :height="size" :alt="`Wrong2 icon`"/>
+</template>

+ 16 - 0
src/components/icons/old icon.vue

@@ -0,0 +1,16 @@
+<script>
+import { defineComponent } from 'vue'
+
+export let size;
+
+export default defineComponent({
+    name: `old iconIcon`,
+    props: {
+        size
+    }
+})
+</script>
+
+<template>
+    <img :src="`/icons/old icon.png`" :width="size" :height="size" :alt="`old icon icon`"/>
+</template>

+ 0 - 24
src/css/App.css

@@ -1,24 +0,0 @@
-#root {
-    width: 100vw;
-    height: 100vh;
-    margin: 0;
-}
-
-.main {
-    width: 100vw;
-    height: 100vh;
-    margin: 0;
-    display: flex;
-    flex-direction: row;
-}
-
-
-@media only screen and (max-width: 768px) {
-    .main {
-        width: 100vw;
-        height: 100vh;
-        margin: 0;
-        display: flex;
-        flex-direction: column;
-    }
-}

Some files were not shown because too many files changed in this diff