Version 1.0.0 - Ajout du design et début search bar
This commit is contained in:
		@@ -4,6 +4,7 @@
 | 
			
		||||
  "private": true,
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "dev": "vite --host --port 8080",
 | 
			
		||||
    "preview": "vite preview --host --port 8080",
 | 
			
		||||
    "build": "vite build"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
    --primary: #FFFFFF;
 | 
			
		||||
    --primary-hover: #292b26;
 | 
			
		||||
    --secondary: #EAEAEA;
 | 
			
		||||
    --tertiary: #cacaca;
 | 
			
		||||
    --tertiary: #d3d3d3;
 | 
			
		||||
    --text: #111210;
 | 
			
		||||
    --text-inverse: #FFFFFF;
 | 
			
		||||
    --text-secondary: #404040;
 | 
			
		||||
@@ -60,6 +60,11 @@ html, body {
 | 
			
		||||
   
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#app {
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    display: flex;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.no-decoration {
 | 
			
		||||
    text-decoration: none !important;
 | 
			
		||||
}   
 | 
			
		||||
 
 | 
			
		||||
@@ -103,7 +103,9 @@ function updateServerInfo() {
 | 
			
		||||
.container {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    gap: 10px;;
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
    gap: 10px;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.itm {
 | 
			
		||||
@@ -146,6 +148,7 @@ function updateServerInfo() {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    background-color: var(--tertiary);
 | 
			
		||||
    border-radius: 0px 0px 10px 10px;
 | 
			
		||||
    z-index: 1000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.menu-content {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,41 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="search">
 | 
			
		||||
        <input type="text" placeholder="Search..." v-model="searchQuery" />
 | 
			
		||||
        <Icon color="#FFFFFF" icon="fa-solid fa-magnifying-glass" style="width: 20px;" />
 | 
			
		||||
        <input ref="searchBar" type="text" placeholder="Insérer votre recherche ici" v-model="searchQuery" />
 | 
			
		||||
        <IconAction
 | 
			
		||||
            icon="fa-solid fa-cloud-arrow-up"
 | 
			
		||||
            color="#FFFFFF"
 | 
			
		||||
            title="Mes fichiers"
 | 
			
		||||
        />
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup>
 | 
			
		||||
import { ref } from 'vue';
 | 
			
		||||
import { onBeforeUnmount, onMounted, ref } from 'vue';
 | 
			
		||||
import IconAction from '../UI/IconAction.vue';
 | 
			
		||||
import { IORequest } from '@/utils/IORequest';
 | 
			
		||||
import Events from '@/utils/Events';
 | 
			
		||||
 | 
			
		||||
const searchBar = ref(null);
 | 
			
		||||
 | 
			
		||||
const searchQuery = ref('');
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
    searchBar.value.addEventListener('change', find);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function find() {
 | 
			
		||||
    if (searchQuery.value.trim() === '') {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    Events.emit("SEARCH_STARTED");
 | 
			
		||||
    IORequest("/SEARCH", (data) => {
 | 
			
		||||
        Events.emit("SEARCH_RESULT", data);
 | 
			
		||||
    }, searchQuery.value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
@@ -15,18 +43,21 @@ const searchQuery = ref('');
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    padding: 10px;
 | 
			
		||||
    background-color: var(--tertiary);
 | 
			
		||||
    gap: 5px;
 | 
			
		||||
    background-color: var(--main);
 | 
			
		||||
    border-radius: 10px;
 | 
			
		||||
    box-shadow: 2px 2px 10px 0px rgba(0, 0, 0, 0.50);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.search input {
 | 
			
		||||
    border: none;
 | 
			
		||||
    outline: none;
 | 
			
		||||
    background: transparent;
 | 
			
		||||
    background: var(--secondary);
 | 
			
		||||
    color: var(--text-primary);
 | 
			
		||||
    border-radius: 10px;;
 | 
			
		||||
    flex: 1;
 | 
			
		||||
    padding: 5px 10px;
 | 
			
		||||
    border-radius: 5px;
 | 
			
		||||
    padding: 10px 10px;
 | 
			
		||||
    border-radius: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.search input::placeholder {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										95
									
								
								src/components/Layout/View.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/components/Layout/View.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <Box v-if="deviceType === 'desktop'" padding="closed" class="view">
 | 
			
		||||
        <IconAction @click="returnDefault()" v-if="!actualComponent.unclosable" icon="fa-solid fa-xmark" class="close"/>
 | 
			
		||||
        <component :is="actualComponent.component" v-bind="actualComponent.props"/>
 | 
			
		||||
    </Box>
 | 
			
		||||
    <div v-else-if="deviceType === 'mobile' && !actualComponent.default" class="view-mobile">
 | 
			
		||||
        <IconAction @click="returnDefault()" v-if="!actualComponent.unclosable" icon="fa-solid fa-xmark" class="close"/>
 | 
			
		||||
        <component :is="actualComponent.component" v-bind="actualComponent.props"/>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script setup>
 | 
			
		||||
import Box from '../UI/Box.vue';
 | 
			
		||||
import Events from '@/utils/Events';
 | 
			
		||||
import { computed, ref, watch } from 'vue';
 | 
			
		||||
import Loading from '@/components/Widget/View/LoadingView.vue'
 | 
			
		||||
import SearchResults from '@/components/Widget/View/SearchResults.vue';
 | 
			
		||||
import Default from '../Widget/View/Default.vue';
 | 
			
		||||
import IconAction from '../UI/IconAction.vue';
 | 
			
		||||
 | 
			
		||||
//TODO: Render compatibility with mobile
 | 
			
		||||
//TODO: Make Default.vue a real default view
 | 
			
		||||
//TODO: Make the search request
 | 
			
		||||
//TODO: Make the medias
 | 
			
		||||
 | 
			
		||||
const deviceType = ref((window.innerWidth < 768 || window.innerHeight < 607) ? 'mobile' : 'desktop');
 | 
			
		||||
 | 
			
		||||
watch(() => window.innerWidth, () => {
 | 
			
		||||
    deviceType.value = (window.innerWidth < 768 || window.innerHeight < 607) ? 'mobile' : 'desktop';
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const defaultComponent = {
 | 
			
		||||
    component: Default,
 | 
			
		||||
    unclosable: true,
 | 
			
		||||
    default: true,
 | 
			
		||||
    props: {}
 | 
			
		||||
};  
 | 
			
		||||
 | 
			
		||||
function returnDefault() {
 | 
			
		||||
    actualComponent.value = defaultComponent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const actualComponent = ref(defaultComponent);
 | 
			
		||||
 | 
			
		||||
Events.on("SEARCH_STARTED", () => {
 | 
			
		||||
    setLoading("Recherche en cours ...")
 | 
			
		||||
})
 | 
			
		||||
Events.on("SEARCH_RESULT", (data) => {
 | 
			
		||||
    console.log("Search results received:", data);
 | 
			
		||||
    actualComponent.value = {
 | 
			
		||||
        component: SearchResults,
 | 
			
		||||
        props: {
 | 
			
		||||
            results: data
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
    function setLoading(messageLoading) {
 | 
			
		||||
        
 | 
			
		||||
    actualComponent.value = {
 | 
			
		||||
        component: Loading,
 | 
			
		||||
        unclosable: true,
 | 
			
		||||
        props: {
 | 
			
		||||
            message: messageLoading
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped>
 | 
			
		||||
 | 
			
		||||
.close {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: 10px;
 | 
			
		||||
    right: 10px;
 | 
			
		||||
    color: var(--text-secondary);
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.view {
 | 
			
		||||
    position: relative;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.view-mobile {
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    top: 0;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    background-color: var(--background-secondary);
 | 
			
		||||
    z-index: 1000;
 | 
			
		||||
    border-radius: 0 !important;
 | 
			
		||||
}   
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
    <div class="settings-container">
 | 
			
		||||
        <Icon style="width: 20px;" class="settings-icon" :icon="icon"/> 
 | 
			
		||||
        <div class="settings-item">
 | 
			
		||||
                <p class="settings-title">{{ title }}</p>
 | 
			
		||||
                <p class="settings-title"><Icon style="width: 20px;" class="settings-icon-replace" :icon="icon"/>  {{ title }}</p>
 | 
			
		||||
               <slot></slot>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
@@ -20,6 +20,16 @@ defineProps({
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped>
 | 
			
		||||
 | 
			
		||||
@media screen and (max-width: 768px) {
 | 
			
		||||
    .settings-icon {
 | 
			
		||||
        display: none;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .settings-icon-replace {
 | 
			
		||||
        display: unset !important;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
    
 | 
			
		||||
.settings-title {
 | 
			
		||||
    font-size: 1.1em;
 | 
			
		||||
@@ -33,6 +43,10 @@ defineProps({
 | 
			
		||||
    margin-top: 1px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.settings-icon-replace {
 | 
			
		||||
    display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.settings-container {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    gap: 7px;
 | 
			
		||||
 
 | 
			
		||||
@@ -86,9 +86,10 @@ defineExpose({
 | 
			
		||||
 <section>
 | 
			
		||||
  <div ref="box" :class="showMenu ? `showed firstbox` : 'firstbox'" @click="showMenu = !showMenu">
 | 
			
		||||
    <template  v-if="firstSlot">
 | 
			
		||||
      <component :is="firstSlot" />
 | 
			
		||||
      <component style="white-space: break-spaces;" :is="firstSlot" />
 | 
			
		||||
    </template>
 | 
			
		||||
    <IconAction
 | 
			
		||||
      class="icon"
 | 
			
		||||
      :icon="showMenu ? 'fa-solid fa-angle-up' : 'fa-solid fa-angle-down'"
 | 
			
		||||
    />
 | 
			
		||||
  </div>
 | 
			
		||||
@@ -114,6 +115,7 @@ defineExpose({
 | 
			
		||||
  font-size: 14px;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.container {
 | 
			
		||||
@@ -148,6 +150,7 @@ defineExpose({
 | 
			
		||||
  padding: 5px;
 | 
			
		||||
  background-color: var(--tertiary);
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  white-space: break-spaces;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.option:hover {
 | 
			
		||||
@@ -160,4 +163,9 @@ defineExpose({
 | 
			
		||||
  padding-bottom: 0; */
 | 
			
		||||
  border-radius: 5px 5px 0 0 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.icon {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -11,7 +11,6 @@
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script setup>
 | 
			
		||||
import { defineProps } from 'vue';
 | 
			
		||||
import Avatar from './Avatar.vue';
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    user: {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="metrics" v-if="metrics">
 | 
			
		||||
    <div class="metrics" v-if="metrics && metrics.length > 0">
 | 
			
		||||
        <div class="metric" v-for="metric in metrics" :key="metric.name">
 | 
			
		||||
            <div class="metric-header">
 | 
			
		||||
                <Icon class="metric-icon" :icon="getIcons(metric.name)" />
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,6 @@
 | 
			
		||||
<script setup>
 | 
			
		||||
import Events from '@/utils/Events';
 | 
			
		||||
import { IORequest } from '@/utils/IORequest';
 | 
			
		||||
import { defineProps } from 'vue';
 | 
			
		||||
import { ref } from 'vue';
 | 
			
		||||
import User from '@/components/UI/User.vue';
 | 
			
		||||
import Role from '@/components/UI/Role.vue';
 | 
			
		||||
 
 | 
			
		||||
@@ -92,6 +92,7 @@ onMounted(() => {
 | 
			
		||||
.version p {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    color: var(--text-secondary);
 | 
			
		||||
}   
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								src/components/Widget/View/Default.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/components/Widget/View/Default.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <p>Test</p>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup>
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										41
									
								
								src/components/Widget/View/LoadingView.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/components/Widget/View/LoadingView.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="loading">
 | 
			
		||||
        <div class="loading-content">
 | 
			
		||||
        <Icon icon="fa-solid fa-spinner" spin-pulse />
 | 
			
		||||
        <span>{{ message }}</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <span class="second">Un peu de patience, le groupe se prépare !</span>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script setup>
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    message: {
 | 
			
		||||
        type: String,
 | 
			
		||||
        default: 'Chargement en cours...'
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped>
 | 
			
		||||
.loading {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    font-size: 2rem;
 | 
			
		||||
    gap: 10px;
 | 
			
		||||
    color: var(--text-tertiary);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.loading-content {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    gap: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.second {
 | 
			
		||||
    font-size: 0.8rem;
 | 
			
		||||
    color: var(--text-secondary);
 | 
			
		||||
    opacity: 0.8;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										3
									
								
								src/components/Widget/View/SearchResults.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/components/Widget/View/SearchResults.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
<template>
 | 
			
		||||
 | 
			
		||||
</template>
 | 
			
		||||
@@ -1,8 +1,10 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <SocketEnvironment>
 | 
			
		||||
        <div class="container">
 | 
			
		||||
             <GuildHeader/>
 | 
			
		||||
                <Box>
 | 
			
		||||
            <Search class="search"/>
 | 
			
		||||
            <div class="left-side">
 | 
			
		||||
                <GuildHeader class="guildheader"/>
 | 
			
		||||
                <Box class="playlist">
 | 
			
		||||
                    <Button @click="router.push('/servers')">Choisir un serveur</Button>
 | 
			
		||||
                    <Button @click="router.push('/terms')">Terms</Button>
 | 
			
		||||
                    <Button @click="router.push('/privacy')">Privacy</Button>
 | 
			
		||||
@@ -10,8 +12,11 @@
 | 
			
		||||
                    <Button @click="globalStore.toogleTheme()">Changer le thème</Button>
 | 
			
		||||
                    <p>{{ guildId }}</p>
 | 
			
		||||
                </Box>
 | 
			
		||||
                <Search/>
 | 
			
		||||
                <Account/>
 | 
			
		||||
                <Account class="account"/>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="queue"></div>
 | 
			
		||||
            <View class="view"></View>
 | 
			
		||||
            <div class="player"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </SocketEnvironment>
 | 
			
		||||
</template>
 | 
			
		||||
@@ -29,6 +34,7 @@ import Account from '@/components/Layout/Account.vue';
 | 
			
		||||
import events from '@/utils/Events.js';
 | 
			
		||||
import GuildHeader from '@/components/Layout/GuildHeader.vue';
 | 
			
		||||
import Search from '@/components/Layout/Search.vue';
 | 
			
		||||
import View from '@/components/Layout/View.vue';
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    guildId: {
 | 
			
		||||
@@ -98,11 +104,105 @@ function checkGuildAvailability() {
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped>  
 | 
			
		||||
 | 
			
		||||
.container {
 | 
			
		||||
    padding: 15px;;;
 | 
			
		||||
    max-width: 400px;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    gap: 20px;
 | 
			
		||||
@media screen and (max-width: 768px), screen and (max-height: 607px) {
 | 
			
		||||
    .container {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        gap: 15px;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
    .left-side {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
        gap: 15px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .guildheader {
 | 
			
		||||
        order: 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .account {
 | 
			
		||||
        order: 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .playlist {
 | 
			
		||||
        order: 2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media screen and (min-width: 769px) and (max-width: 1280px) and (min-height: 607px) {
 | 
			
		||||
    .queue {
 | 
			
		||||
        display: none
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    .container {
 | 
			
		||||
        display: grid;
 | 
			
		||||
        grid-template-columns: 0.8fr repeat(2, 1fr);
 | 
			
		||||
        grid-template-rows: 0.1fr repeat(2, 1fr) 0.5fr;
 | 
			
		||||
        grid-column-gap: 15px;
 | 
			
		||||
        grid-row-gap: 15px;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .left-side { grid-area: 1 / 1 / 5 / 2; }
 | 
			
		||||
    .player { grid-area: 4 / 2 / 5 / 4; }
 | 
			
		||||
    .search { grid-area: 1 / 2 / 2 / 4; }
 | 
			
		||||
    .view { grid-area: 2 / 2 / 4 / 4; }
 | 
			
		||||
    
 | 
			
		||||
    .left-side {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
        gap: 15px;
 | 
			
		||||
        height: 100%;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .playlist {
 | 
			
		||||
        flex: 1;
 | 
			
		||||
    }
 | 
			
		||||
      
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media screen and (min-width: 1281px) {
 | 
			
		||||
    .container {
 | 
			
		||||
        display: grid;
 | 
			
		||||
        grid-template-columns: 0.7fr repeat(2, 1fr) 0.8fr;
 | 
			
		||||
        grid-template-rows: 0.1fr repeat(2, 1fr) 0.5fr;
 | 
			
		||||
        grid-column-gap: 15px;
 | 
			
		||||
        grid-row-gap: 15px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .left-side { grid-area: 1 / 1 / 5 / 2; }
 | 
			
		||||
    .player { grid-area: 4 / 2 / 5 / 4; }
 | 
			
		||||
    .search { grid-area: 1 / 2 / 2 / 4; }
 | 
			
		||||
    .queue { grid-area: 1 / 4 / 5 / 5; }
 | 
			
		||||
    .view { grid-area: 2 / 2 / 4 / 4; }
 | 
			
		||||
 | 
			
		||||
    .left-side {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
        gap: 15px;
 | 
			
		||||
        height: 100%;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .playlist {
 | 
			
		||||
        flex: 1;
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.container {
 | 
			
		||||
    padding: 15px;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.queue, .view, .player {
 | 
			
		||||
    background-color: var(--secondary);
 | 
			
		||||
    border-radius: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
		Reference in New Issue
	
	Block a user