Version 1.0.0 - Création du Header
							
								
								
									
										
											BIN
										
									
								
								public/logo.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 24 KiB  | 
| 
		 Before Width: | Height: | Size: 27 KiB  | 
@@ -1,54 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<svg
 | 
			
		||||
   width="1024"
 | 
			
		||||
   height="1024"
 | 
			
		||||
   viewBox="0 0 1024 1024"
 | 
			
		||||
   fill="none"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   sodipodi:docname="logoblack.svg"
 | 
			
		||||
   inkscape:version="1.4 (86a8ad7, 2024-10-11)"
 | 
			
		||||
   inkscape:export-filename="logoblack.png"
 | 
			
		||||
   inkscape:export-xdpi="96"
 | 
			
		||||
   inkscape:export-ydpi="96"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs2" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="namedview2"
 | 
			
		||||
     pagecolor="#ffffff"
 | 
			
		||||
     bordercolor="#000000"
 | 
			
		||||
     borderopacity="0.25"
 | 
			
		||||
     inkscape:showpageshadow="2"
 | 
			
		||||
     inkscape:pageopacity="0.0"
 | 
			
		||||
     inkscape:pagecheckerboard="0"
 | 
			
		||||
     inkscape:deskcolor="#d1d1d1"
 | 
			
		||||
     inkscape:zoom="0.37459218"
 | 
			
		||||
     inkscape:cx="-413.78333"
 | 
			
		||||
     inkscape:cy="385.75285"
 | 
			
		||||
     inkscape:window-width="3840"
 | 
			
		||||
     inkscape:window-height="2054"
 | 
			
		||||
     inkscape:window-x="2869"
 | 
			
		||||
     inkscape:window-y="-11"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:current-layer="svg2" />
 | 
			
		||||
  <g
 | 
			
		||||
     id="g1"
 | 
			
		||||
     transform="matrix(1.6150014,0,0,1.6150014,-132.31608,-233.05676)">
 | 
			
		||||
    <path
 | 
			
		||||
       d="m 416.749,219.63505 c 0,71.9 -0.1,73.4 -6.6,95 -6.3,20.6 -16.9,41.5 -31.3,61 -3.8,5.1 -16.8,20.4 -28.9,34 -25.8,28.9 -34.5,39.5 -45.1,55.2 -22.2,32.8 -33.69997,62.8 -37.19997,97.7 -5.6,55 23.19997,111.3 71.39997,139.5 6.4,3.7 19.3,9.5 25.5,11.3 l 2.2,0.6 v -91.3 c 0,-96.6 0.2,-101.5 4.9,-120.9 6.1,-25.7 18.6,-49 40.8,-76.2 15.1,-18.6 32.5,-42 39.2,-52.8 22.1,-35.6 33.2,-70.9 31.8,-101.3 -0.9,-20.7 -5.7,-38.8 -15.2,-58.1 -7.9,-15.8 -16.5,-28 -28.2,-39.8 -7.8,-7.8 -21,-18.69999 -22.7,-18.69999 -0.3,0 -0.6,29.19999 -0.6,64.79999 z"
 | 
			
		||||
       fill="white"
 | 
			
		||||
       id="path1"
 | 
			
		||||
       style="fill:#111210;fill-opacity:1"
 | 
			
		||||
       sodipodi:nodetypes="sccccccccsccccccss" />
 | 
			
		||||
    <path
 | 
			
		||||
       d="m 400.749,611.73505 v 156.1 h 3.8 c 2,0 4.3,-0.4 5,-0.8 1,-0.7 1.2,-22.7 1,-108 -0.3,-87 -0.1,-107.2 1,-107.2 5.2,0 15.7,9 19.7,17.1 5.3,10.3 5.5,13.2 5.5,81.1 0,52.1 0.2,62.8 1.4,62.8 0.7,0 7.1,-2.9 14.2,-6.5 41.3,-20.7 69.3,-57.3 76.9,-100.5 2,-11.1 2.3,-33.4 0.6,-43.1 -3.2,-18.9 -12.1,-40 -23.2,-55 -22.8,-30.7 -56.4,-48.7 -96.1,-51.5 l -9.8,-0.7 z"
 | 
			
		||||
       fill="#7A258D"
 | 
			
		||||
       id="path2"
 | 
			
		||||
       style="fill:#cd034f;fill-opacity:1"
 | 
			
		||||
       sodipodi:nodetypes="ccsccscssccccccc" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 2.4 KiB  | 
@@ -5,10 +5,5 @@
 | 
			
		||||
  import { onMounted } from 'vue'
 | 
			
		||||
  import { useGlobalStore } from '@/stores/globalStore';
 | 
			
		||||
  const globalStore = useGlobalStore();
 | 
			
		||||
 | 
			
		||||
  onMounted(() => {
 | 
			
		||||
    
 | 
			
		||||
  });
 | 
			
		||||
  console.log("Subsonics Chopin - App Vue Loaded");
 | 
			
		||||
  
 | 
			
		||||
</script>
 | 
			
		||||
@@ -43,6 +43,7 @@ html, body {
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    overflow-x: hidden;
 | 
			
		||||
    background-color: var(--primary);
 | 
			
		||||
    transition: all 0.5s ease-in-out;
 | 
			
		||||
   
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -82,3 +83,6 @@ a {
 | 
			
		||||
    background: #ffffffa8;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
.full {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								src/assets/LogoDark.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,28 @@
 | 
			
		||||
<template>
 | 
			
		||||
<svg
 | 
			
		||||
   width="1024"
 | 
			
		||||
   height="1024"
 | 
			
		||||
   viewBox="0 0 1024 1024"
 | 
			
		||||
   fill="none"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs2" />
 | 
			
		||||
  <g
 | 
			
		||||
     id="g1"
 | 
			
		||||
     transform="translate(-7.748334,-6.62121)">
 | 
			
		||||
    <path
 | 
			
		||||
       d="m 548.34145,130.19117 c 0,115.54868 -0.16071,117.9593 -10.60669,152.67212 -10.12458,33.10576 -27.15957,66.69362 -50.30145,98.03158 -6.1069,8.19609 -26.99887,32.78433 -46.44447,54.64055 -41.46255,46.44447 -55.4441,63.47948 -72.4791,88.71055 -35.67706,52.71207 -54.15838,100.92431 -59.78313,157.01124 -8.99964,88.38913 37.28408,178.86745 114.7451,224.18697 10.28528,5.94617 31.01656,15.26722 40.98041,18.15995 l 3.53557,0.96423 V 777.84243 c 0,-155.24346 0.32142,-163.11813 7.87467,-194.29539 9.80316,-41.30183 29.8916,-78.74668 65.56865,-122.45912 24.26685,-29.8916 52.22995,-67.49715 62.99735,-84.85357 35.51637,-57.21187 53.3549,-113.94161 51.105,-162.79669 C 654.08699,180.1712 646.37303,151.08314 631.10583,120.0666 618.40993,94.6748 604.58907,75.068476 585.7863,56.105001 573.2511,43.569813 552.03772,26.05272 549.30569,26.05272 c -0.48212,0 -0.96424,46.926551 -0.96424,104.13845 z"
 | 
			
		||||
       fill="#111210"
 | 
			
		||||
       id="path1"
 | 
			
		||||
       style="stroke-width:1.60707" />
 | 
			
		||||
    <path
 | 
			
		||||
       d="m 522.62825,760.3253 v 250.8644 h 6.10687 c 3.21417,0 6.91044,-0.6429 8.03538,-1.2856 1.60709,-1.125 1.9285,-36.48067 1.60709,-173.56414 -0.48213,-139.81555 -0.16071,-172.27846 1.60707,-172.27846 8.35679,0 25.23107,14.46368 31.65938,27.48099 8.5175,16.55287 8.83891,21.21339 8.83891,130.33379 0,83.72861 0.32142,100.9243 2.2499,100.9243 1.12496,0 11.41024,-4.66051 22.82047,-10.44597 66.3722,-33.26645 111.3703,-92.0854 123.58408,-161.51106 3.21415,-17.83853 3.69627,-53.67631 0.96424,-69.26493 -5.14264,-30.37371 -19.4456,-64.283 -37.28415,-88.38913 -36.6413,-49.3372 -90.63903,-78.26456 -154.4399,-82.76435 l -15.74934,-1.12496 z"
 | 
			
		||||
       fill="#7A258D"
 | 
			
		||||
       id="path2"
 | 
			
		||||
       style="fill:#cd034f;fill-opacity:1;stroke-width:1.60707" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
</template>
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<template>
 | 
			
		||||
<svg
 | 
			
		||||
   width="1024"
 | 
			
		||||
   height="1024"
 | 
			
		||||
@@ -6,35 +6,10 @@
 | 
			
		||||
   fill="none"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   sodipodi:docname="logo.svg"
 | 
			
		||||
   inkscape:version="1.4 (86a8ad7, 2024-10-11)"
 | 
			
		||||
   inkscape:export-filename="logo.png"
 | 
			
		||||
   inkscape:export-xdpi="96"
 | 
			
		||||
   inkscape:export-ydpi="96"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs2" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="namedview2"
 | 
			
		||||
     pagecolor="#ffffff"
 | 
			
		||||
     bordercolor="#000000"
 | 
			
		||||
     borderopacity="0.25"
 | 
			
		||||
     inkscape:showpageshadow="2"
 | 
			
		||||
     inkscape:pageopacity="0.0"
 | 
			
		||||
     inkscape:pagecheckerboard="0"
 | 
			
		||||
     inkscape:deskcolor="#d1d1d1"
 | 
			
		||||
     inkscape:zoom="1.0595067"
 | 
			
		||||
     inkscape:cx="98.158891"
 | 
			
		||||
     inkscape:cy="738.55127"
 | 
			
		||||
     inkscape:window-width="3840"
 | 
			
		||||
     inkscape:window-height="2054"
 | 
			
		||||
     inkscape:window-x="2869"
 | 
			
		||||
     inkscape:window-y="-11"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:current-layer="svg2" />
 | 
			
		||||
  <g
 | 
			
		||||
     id="g1"
 | 
			
		||||
     transform="translate(-7.748334,-6.62121)">
 | 
			
		||||
@@ -50,3 +25,4 @@
 | 
			
		||||
       style="fill:#cd034f;fill-opacity:1;stroke-width:1.60707" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
</template>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.0 KiB  | 
@@ -1,4 +1,4 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<template>
 | 
			
		||||
<svg
 | 
			
		||||
   width="1024"
 | 
			
		||||
   height="1024"
 | 
			
		||||
@@ -6,35 +6,10 @@
 | 
			
		||||
   fill="none"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   sodipodi:docname="logo.svg"
 | 
			
		||||
   inkscape:version="1.4 (86a8ad7, 2024-10-11)"
 | 
			
		||||
   inkscape:export-filename="logo.png"
 | 
			
		||||
   inkscape:export-xdpi="96"
 | 
			
		||||
   inkscape:export-ydpi="96"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs2" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="namedview2"
 | 
			
		||||
     pagecolor="#ffffff"
 | 
			
		||||
     bordercolor="#000000"
 | 
			
		||||
     borderopacity="0.25"
 | 
			
		||||
     inkscape:showpageshadow="2"
 | 
			
		||||
     inkscape:pageopacity="0.0"
 | 
			
		||||
     inkscape:pagecheckerboard="0"
 | 
			
		||||
     inkscape:deskcolor="#d1d1d1"
 | 
			
		||||
     inkscape:zoom="1.0595067"
 | 
			
		||||
     inkscape:cx="98.158891"
 | 
			
		||||
     inkscape:cy="738.55127"
 | 
			
		||||
     inkscape:window-width="3840"
 | 
			
		||||
     inkscape:window-height="2054"
 | 
			
		||||
     inkscape:window-x="2869"
 | 
			
		||||
     inkscape:window-y="-11"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:current-layer="svg2" />
 | 
			
		||||
  <g
 | 
			
		||||
     id="g1"
 | 
			
		||||
     transform="translate(-7.748334,-6.62121)">
 | 
			
		||||
@@ -50,3 +25,4 @@
 | 
			
		||||
       style="fill:#ffffff;fill-opacity:1;stroke-width:1.60707" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
</template>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.0 KiB  | 
@@ -39,7 +39,6 @@ function goToSettings() {
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    gap: 30px;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
}
 | 
			
		||||
.user-action {
 | 
			
		||||
    display: flex;
 | 
			
		||||
							
								
								
									
										87
									
								
								src/components/Features/HeaderGuild.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,87 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <Box padding="closed">
 | 
			
		||||
        <div class="container">
 | 
			
		||||
            <SubsonicsLogo/>
 | 
			
		||||
            <div class="server-box">
 | 
			
		||||
                 <Box ref="collapsedBoxRef" level="second" padding="closed">
 | 
			
		||||
                        <div v-if="server" class="itm">
 | 
			
		||||
                            <ServerItem :server="server"/>
 | 
			
		||||
                            <div class="actions">
 | 
			
		||||
                                <ListenBox>{{ server.members.length + 1}}</ListenBox>
 | 
			
		||||
                                <IconAction @click="showMenu = !showMenu" :icon="showMenu ? 'fa-solid fa-angle-up' : 'fa-solid fa-angle-down'"/>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <Error v-else><ServerItem/></Error>
 | 
			
		||||
                        <div v-if="showMenu">
 | 
			
		||||
                            <p>Other items</p>
 | 
			
		||||
                        </div>
 | 
			
		||||
                </Box>
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </Box>
 | 
			
		||||
</template>
 | 
			
		||||
<script setup>
 | 
			
		||||
import SubsonicsLogo from '@/components/UI/SubsonicsLogo.vue';
 | 
			
		||||
import Box from '@/components/UI/Box.vue';
 | 
			
		||||
import ServerItem from '@/components/Widget/ServerItem.vue';
 | 
			
		||||
import IconAction from '../UI/IconAction.vue';
 | 
			
		||||
import ListenBox from '@/components/UI/ListenBox.vue';
 | 
			
		||||
import Error from '@/components/UI/Error.vue';
 | 
			
		||||
import { IORequest } from '@/utils/IORequest';
 | 
			
		||||
import { ref, onMounted } from 'vue';
 | 
			
		||||
import events from '@/utils/Events';
 | 
			
		||||
import { watch } from 'vue';
 | 
			
		||||
 | 
			
		||||
const server = ref(undefined)
 | 
			
		||||
const showMenu = ref(false);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
events.on("UPDATE", () => {
 | 
			
		||||
    updateServerInfo();
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
    updateServerInfo();
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
function updateServerInfo() {
 | 
			
		||||
    IORequest("/GUILD/INFO", (data) => {
 | 
			
		||||
        server.value = data;
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped>
 | 
			
		||||
.container {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    gap: 10px;;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.itm {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.actions {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    gap: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.server-box {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    position: relative;
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.collapsed-box {
 | 
			
		||||
  height: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
   <div class="splash-container">
 | 
			
		||||
      <div class="splash-title">
 | 
			
		||||
         <img src="/logo-white.svg" alt="Logo"/>
 | 
			
		||||
         <LogoWhite class="img"/>
 | 
			
		||||
         <h1>Subsonics</h1>
 | 
			
		||||
      </div>
 | 
			
		||||
      <slot></slot> 
 | 
			
		||||
@@ -9,6 +9,8 @@
 | 
			
		||||
 | 
			
		||||
</template>
 | 
			
		||||
<script setup>
 | 
			
		||||
import LogoWhite from '@/assets/LogoWhite.vue';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped>
 | 
			
		||||
@@ -31,7 +33,7 @@
 | 
			
		||||
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   img {
 | 
			
		||||
   .img {
 | 
			
		||||
      width: 100px;
 | 
			
		||||
      height: 100px;
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								src/components/UI/ListenBox.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,24 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="listen-box">
 | 
			
		||||
        <Icon font-size="12px" class="listen-icon" icon="fa-solid fa-user" />
 | 
			
		||||
        <p><slot></slot></p>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
<style scoped>
 | 
			
		||||
    .listen-box {
 | 
			
		||||
        color: white;
 | 
			
		||||
        background-color: var(--main);
 | 
			
		||||
        padding: 4px 8px;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        border-radius: 4px;
 | 
			
		||||
        gap: 5px;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    p {
 | 
			
		||||
        margin: 0;
 | 
			
		||||
        width: 9px;
 | 
			
		||||
        height: 16px;
 | 
			
		||||
    }
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										25
									
								
								src/components/UI/SubsonicsLogo.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,25 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div>
 | 
			
		||||
        <LogoDark class="img" v-if="globalStore.theme == 'light'"/>
 | 
			
		||||
        <LogoLight class="img" v-else/>
 | 
			
		||||
        <h1>Subsonics</h1>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script setup>
 | 
			
		||||
import LogoDark from '@/assets/LogoDark.vue';
 | 
			
		||||
import LogoLight from '@/assets/LogoLight.vue';
 | 
			
		||||
import { useGlobalStore } from '@/stores/globalStore';
 | 
			
		||||
 | 
			
		||||
const globalStore = useGlobalStore();
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped>
 | 
			
		||||
    .img {
 | 
			
		||||
      width: 100px;
 | 
			
		||||
      height: 100px;
 | 
			
		||||
    }  
 | 
			
		||||
    div {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        gap: 10px;
 | 
			
		||||
    }
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										54
									
								
								src/components/Widget/ServerItem.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,54 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="container-avatar">
 | 
			
		||||
        <ServerAvatar :server-id="server.id" :src="server.icon"/>
 | 
			
		||||
        <div class="info">
 | 
			
		||||
            <p class="name">{{ server.name }}</p>
 | 
			
		||||
            <p class="data"><Icon style="font-size: 10px;" :color="server.connected ? '#0BFF89' : '#FF0A0A'" icon="fa-solid fa-circle"/> {{ server.connected ? 'En ligne' : 'Hors ligne' }} - {{ server.serverMember }} membres</p>
 | 
			
		||||
         </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script setup>
 | 
			
		||||
import ServerAvatar from '../UI/ServerAvatar.vue';
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    server: {
 | 
			
		||||
        type: Object,
 | 
			
		||||
        default: () => ({
 | 
			
		||||
            id: '',
 | 
			
		||||
            name: 'Aucun serveur séléctionné',
 | 
			
		||||
            owner: false,
 | 
			
		||||
            icon: '',
 | 
			
		||||
            members: [],
 | 
			
		||||
            serverMember: 0,
 | 
			
		||||
            connected: false
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped>
 | 
			
		||||
.container-avatar {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    gap: 10px;;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
p {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.data {
 | 
			
		||||
    color: var(--text-secondary);
 | 
			
		||||
    font-size: 0.8em;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    gap: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.info {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    gap: 5px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,13 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <Box no-shadow level="second" padding="closed">
 | 
			
		||||
        <div class="container-list">
 | 
			
		||||
            <div class="container-avatar">
 | 
			
		||||
                <ServerAvatar :server-id="server.id" :src="server.icon"/>
 | 
			
		||||
                <div class="info">
 | 
			
		||||
                    <p class="name">{{ server.name }}</p>
 | 
			
		||||
                    <p class="data"><Icon style="font-size: 10px;" :color="server.connected ? '#0BFF89' : '#FF0A0A'" icon="fa-solid fa-circle"/> {{ server.connected ? 'En ligne' : 'Hors ligne' }} - {{ server.serverMember }} membres</p>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <ServerItem :server="server"/>
 | 
			
		||||
            <ServerOnlinePicture class="sop" :key="server.id" v-if="server.members.length > 0" :members="server.members"/>
 | 
			
		||||
            <Button class="btn" @click="access()">Accéder</Button>
 | 
			
		||||
        </div>
 | 
			
		||||
@@ -15,12 +9,11 @@
 | 
			
		||||
</template>
 | 
			
		||||
<script setup>
 | 
			
		||||
import Box from '@/components/UI/Box.vue';
 | 
			
		||||
import ServerAvatar from '../UI/ServerAvatar.vue';
 | 
			
		||||
import Button from '../UI/Button.vue';
 | 
			
		||||
import IconAction from '../UI/IconAction.vue';
 | 
			
		||||
import { useGlobalStore } from '@/stores/globalStore';
 | 
			
		||||
import { useRouter } from 'vue-router';
 | 
			
		||||
import ServerOnlinePicture from '@/components/Widget/ServerOnlinePicture.vue';
 | 
			
		||||
import ServerItem from '@/components/Widget/ServerItem.vue';
 | 
			
		||||
const router = useRouter();
 | 
			
		||||
 | 
			
		||||
const globalStore = useGlobalStore();
 | 
			
		||||
@@ -46,11 +39,6 @@ function access() {
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped>
 | 
			
		||||
.container-avatar {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    gap: 10px;;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.actions {
 | 
			
		||||
    display: flex;
 | 
			
		||||
@@ -78,25 +66,17 @@ function access() {
 | 
			
		||||
.container-list {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
    align-items: center;    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
p {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.data {
 | 
			
		||||
    color: var(--text-secondary);
 | 
			
		||||
    font-size: 0.8em;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    gap: 3px;
 | 
			
		||||
    position: relative;    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.info {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    gap: 5px;
 | 
			
		||||
.sop {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: 50%;
 | 
			
		||||
    left: 50%;
 | 
			
		||||
    transform: translate(-50%, -50%);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -10,6 +10,7 @@ import { socket } from "@/socket"
 | 
			
		||||
import { useLoginStore } from './stores/loginStore'
 | 
			
		||||
import { useGlobalStore } from './stores/globalStore'
 | 
			
		||||
import Interface from './views/Interface.vue'
 | 
			
		||||
import events from './utils/Events'
 | 
			
		||||
 | 
			
		||||
const router = createRouter({
 | 
			
		||||
    history: createWebHistory(),
 | 
			
		||||
@@ -33,6 +34,8 @@ router.beforeEach((to, from, next) => {
 | 
			
		||||
  const loginStore = useLoginStore()
 | 
			
		||||
  const globalStore = useGlobalStore()
 | 
			
		||||
  console.log(from.matched)
 | 
			
		||||
  events.clear()
 | 
			
		||||
  console.log("Clearing events")
 | 
			
		||||
  if(from.matched.length == 0) {
 | 
			
		||||
    globalStore.setLastRoute(null)
 | 
			
		||||
  } else {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								src/utils/Events.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,23 @@
 | 
			
		||||
const Events = new Map()
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    on(eventName, fn) {
 | 
			
		||||
        if(!Events.has(eventName)) {
 | 
			
		||||
            Events.set(eventName, [])
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Events.get(eventName).push(fn)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    off(eventName, fn) {
 | 
			
		||||
        throw {message:'Not implemented'}
 | 
			
		||||
    },
 | 
			
		||||
    emit(eventName, data) {
 | 
			
		||||
        if(Events.has(eventName)) {
 | 
			
		||||
            Events.get(eventName).forEach(fn => fn(data))
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    clear() {
 | 
			
		||||
        Events.clear()
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
@@ -11,6 +11,7 @@ import { useRouter } from 'vue-router';
 | 
			
		||||
import { IOListener, IORequest } from '@/utils/IORequest';
 | 
			
		||||
import { useUserStore } from '@/stores/userStore';
 | 
			
		||||
import { useGlobalStore } from '@/stores/globalStore';
 | 
			
		||||
import events from '@/utils/Events.js';
 | 
			
		||||
 | 
			
		||||
    const router = useRouter();
 | 
			
		||||
    const interuptionMessage = ref(null);
 | 
			
		||||
@@ -29,16 +30,15 @@ import { useGlobalStore } from '@/stores/globalStore';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    IOListener("/USER/READY", () => {
 | 
			
		||||
        IORequest("/USER/INFO", (data) => {
 | 
			
		||||
       IORequest("/USER/INFO", (data) => {
 | 
			
		||||
            interuptionMessage.value = null;
 | 
			
		||||
            userStore.setUserInfo(data);
 | 
			
		||||
            events.emit("UPDATE")
 | 
			
		||||
            console.log("User info received:", data);
 | 
			
		||||
            globalStore.setLoading(false);
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    IOListener("AUTH_ERROR", (error) => {
 | 
			
		||||
        console.error("Authentication error:", error);
 | 
			
		||||
        loginStore.setToken(null);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <SocketEnvironment>
 | 
			
		||||
        <div class="container">
 | 
			
		||||
             <HeaderGuild/>
 | 
			
		||||
                <Box>
 | 
			
		||||
                    <Button @click="router.push('/servers')">Choisir un serveur</Button>
 | 
			
		||||
                    <Button @click="router.push('/terms')">Terms</Button>
 | 
			
		||||
@@ -8,7 +9,7 @@
 | 
			
		||||
                    <Button @click="globalStore.toogleTheme()">Changer le thème</Button>
 | 
			
		||||
                    <p>{{ guildId }}</p>
 | 
			
		||||
                </Box>
 | 
			
		||||
                <UserAction/>
 | 
			
		||||
                <Account/>
 | 
			
		||||
        </div>
 | 
			
		||||
    </SocketEnvironment>
 | 
			
		||||
</template>
 | 
			
		||||
@@ -16,13 +17,15 @@
 | 
			
		||||
import Box from '@/components/UI/Box.vue';
 | 
			
		||||
import Button from '@/components/UI/Button.vue';
 | 
			
		||||
import SocketEnvironment from '@/utils/SocketEnvironment.vue';
 | 
			
		||||
import UserAction from '@/components/Features/UserAction.vue';
 | 
			
		||||
import { watch } from 'vue';
 | 
			
		||||
import { useRouter } from 'vue-router';
 | 
			
		||||
import { useGlobalStore } from '@/stores/globalStore';
 | 
			
		||||
import { useUserStore } from '@/stores/userStore';
 | 
			
		||||
import { IOListener, IORequest } from '@/utils/IORequest';
 | 
			
		||||
import { onMounted, ref } from 'vue';
 | 
			
		||||
import Account from '@/components/Features/Account.vue';
 | 
			
		||||
import events from '@/utils/Events.js';
 | 
			
		||||
import HeaderGuild from '@/components/Features/HeaderGuild.vue';
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    guildId: {
 | 
			
		||||
@@ -54,11 +57,9 @@ onMounted(() => {
 | 
			
		||||
    } 
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
watch(() => userStore.userInfo, (newValue, oldValue) => {
 | 
			
		||||
    if(userStore.userInfo) {
 | 
			
		||||
        checkGuildAvailability();
 | 
			
		||||
    }
 | 
			
		||||
}, { immediate: true });    
 | 
			
		||||
events.on("UPDATE", () => {
 | 
			
		||||
    checkGuildAvailability();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function loadInteface() {
 | 
			
		||||
    if(alreadyLoaded.value) return;
 | 
			
		||||
@@ -99,18 +100,10 @@ function checkGuildAvailability() {
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped>  
 | 
			
		||||
.container {
 | 
			
		||||
    padding: 20px;
 | 
			
		||||
    max-width: 800px;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    gap: 20px;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.container {
 | 
			
		||||
    padding: 20px;;
 | 
			
		||||
    max-width: 800px;
 | 
			
		||||
    max-width: 400px;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    gap: 20px;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
<script setup>
 | 
			
		||||
import UserAction from '@/components/Features/UserAction.vue';
 | 
			
		||||
import Splash from '@/components/Layout/Splash.vue';
 | 
			
		||||
import Box from '@/components/UI/Box.vue';
 | 
			
		||||
import SocketEnvironment from "../utils/SocketEnvironment.vue"
 | 
			
		||||
@@ -11,6 +10,7 @@ import ReturnHomeButton from '@/components/Widget/ReturnHomeButton.vue';
 | 
			
		||||
import { ref } from 'vue';
 | 
			
		||||
import ServerListItem from '@/components/Widget/ServerListItem.vue';
 | 
			
		||||
import Info from '@/components/UI/Info.vue';
 | 
			
		||||
import Account from '@/components/Features/Account.vue';
 | 
			
		||||
 | 
			
		||||
const globalStore = useGlobalStore();
 | 
			
		||||
const userStore = useUserStore();
 | 
			
		||||
@@ -34,7 +34,7 @@ fetch('/information.json')
 | 
			
		||||
 | 
			
		||||
function inviteSubsonics() {
 | 
			
		||||
    
 | 
			
		||||
    window.open(botInviteUrl.value, '_blank');
 | 
			
		||||
    window.open(botInviteUrl.value, '_blank', `popup,width=600,height=600,left=${(window.innerWidth - 600) / 2},top=${(window.innerHeight - 600) / 2}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Vérifier RaphX pourquoi ca plante !
 | 
			
		||||
@@ -58,7 +58,7 @@ function inviteSubsonics() {
 | 
			
		||||
                    <Button :disabled="!hasLink" @click="inviteSubsonics()"><Icon icon="fa-solid fa-user-plus"/>Inviter Subsonics</Button>
 | 
			
		||||
                </div>
 | 
			
		||||
            </Box>
 | 
			
		||||
            <UserAction/>
 | 
			
		||||
            <Account class="full"/>
 | 
			
		||||
            </div>
 | 
			
		||||
        </Splash>
 | 
			
		||||
    </SocketEnvironment>
 | 
			
		||||
 
 | 
			
		||||