base page
This commit is contained in:
parent
8b898e1228
commit
2e7ba45484
BIN
public/Dolphin/dolphin-logo.png
Normal file
BIN
public/Dolphin/dolphin-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
BIN
public/Dolphin/dolphinfav.ico
Normal file
BIN
public/Dolphin/dolphinfav.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 361 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB |
1
public/svg/large-triangles.svg
Normal file
1
public/svg/large-triangles.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns='http://www.w3.org/2000/svg' width='750' height='625' viewBox='0 0 1080 900'><rect fill='#F6F8FF' width='1080' height='900'/><g fill-opacity='0.02'><polygon fill='#444' points='90 150 0 300 180 300'/><polygon points='90 150 180 0 0 0'/><polygon fill='#AAA' points='270 150 360 0 180 0'/><polygon fill='#DDD' points='450 150 360 300 540 300'/><polygon fill='#999' points='450 150 540 0 360 0'/><polygon points='630 150 540 300 720 300'/><polygon fill='#DDD' points='630 150 720 0 540 0'/><polygon fill='#444' points='810 150 720 300 900 300'/><polygon fill='#FFF' points='810 150 900 0 720 0'/><polygon fill='#DDD' points='990 150 900 300 1080 300'/><polygon fill='#444' points='990 150 1080 0 900 0'/><polygon fill='#DDD' points='90 450 0 600 180 600'/><polygon points='90 450 180 300 0 300'/><polygon fill='#666' points='270 450 180 600 360 600'/><polygon fill='#AAA' points='270 450 360 300 180 300'/><polygon fill='#DDD' points='450 450 360 600 540 600'/><polygon fill='#999' points='450 450 540 300 360 300'/><polygon fill='#999' points='630 450 540 600 720 600'/><polygon fill='#FFF' points='630 450 720 300 540 300'/><polygon points='810 450 720 600 900 600'/><polygon fill='#DDD' points='810 450 900 300 720 300'/><polygon fill='#AAA' points='990 450 900 600 1080 600'/><polygon fill='#444' points='990 450 1080 300 900 300'/><polygon fill='#222' points='90 750 0 900 180 900'/><polygon points='270 750 180 900 360 900'/><polygon fill='#DDD' points='270 750 360 600 180 600'/><polygon points='450 750 540 600 360 600'/><polygon points='630 750 540 900 720 900'/><polygon fill='#444' points='630 750 720 600 540 600'/><polygon fill='#AAA' points='810 750 720 900 900 900'/><polygon fill='#666' points='810 750 900 600 720 600'/><polygon fill='#999' points='990 750 900 900 1080 900'/><polygon fill='#999' points='180 0 90 150 270 150'/><polygon fill='#444' points='360 0 270 150 450 150'/><polygon fill='#FFF' points='540 0 450 150 630 150'/><polygon points='900 0 810 150 990 150'/><polygon fill='#222' points='0 300 -90 450 90 450'/><polygon fill='#FFF' points='0 300 90 150 -90 150'/><polygon fill='#FFF' points='180 300 90 450 270 450'/><polygon fill='#666' points='180 300 270 150 90 150'/><polygon fill='#222' points='360 300 270 450 450 450'/><polygon fill='#FFF' points='360 300 450 150 270 150'/><polygon fill='#444' points='540 300 450 450 630 450'/><polygon fill='#222' points='540 300 630 150 450 150'/><polygon fill='#AAA' points='720 300 630 450 810 450'/><polygon fill='#666' points='720 300 810 150 630 150'/><polygon fill='#FFF' points='900 300 810 450 990 450'/><polygon fill='#999' points='900 300 990 150 810 150'/><polygon points='0 600 -90 750 90 750'/><polygon fill='#666' points='0 600 90 450 -90 450'/><polygon fill='#AAA' points='180 600 90 750 270 750'/><polygon fill='#444' points='180 600 270 450 90 450'/><polygon fill='#444' points='360 600 270 750 450 750'/><polygon fill='#999' points='360 600 450 450 270 450'/><polygon fill='#666' points='540 600 630 450 450 450'/><polygon fill='#222' points='720 600 630 750 810 750'/><polygon fill='#FFF' points='900 600 810 750 990 750'/><polygon fill='#222' points='900 600 990 450 810 450'/><polygon fill='#DDD' points='0 900 90 750 -90 750'/><polygon fill='#444' points='180 900 270 750 90 750'/><polygon fill='#FFF' points='360 900 450 750 270 750'/><polygon fill='#AAA' points='540 900 630 750 450 750'/><polygon fill='#FFF' points='720 900 810 750 630 750'/><polygon fill='#222' points='900 900 990 750 810 750'/><polygon fill='#222' points='1080 300 990 450 1170 450'/><polygon fill='#FFF' points='1080 300 1170 150 990 150'/><polygon points='1080 600 990 750 1170 750'/><polygon fill='#666' points='1080 600 1170 450 990 450'/><polygon fill='#DDD' points='1080 900 1170 750 990 750'/></g></svg>
|
||||
12
src/App.vue
12
src/App.vue
|
|
@ -1,11 +1,7 @@
|
|||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
import { RouterView } from "vue-router";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>You did it!</h1>
|
||||
<p>
|
||||
Visit <a href="https://vuejs.org/" target="_blank" rel="noopener">vuejs.org</a> to read the
|
||||
documentation
|
||||
</p>
|
||||
<RouterView />
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
|
|||
14
src/assets/css/animation.css
Normal file
14
src/assets/css/animation.css
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
@keyframes popUp {
|
||||
0% {
|
||||
transform: scale(0.5);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-pop-up {
|
||||
animation: popUp 0.5s ease-out forwards;
|
||||
}
|
||||
242
src/assets/css/font.css
Normal file
242
src/assets/css/font.css
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: italic;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkC3kaWzU.woff2) format("woff2");
|
||||
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: italic;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkAnkaWzU.woff2) format("woff2");
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: italic;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkCnkaWzU.woff2) format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: italic;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkBXkaWzU.woff2) format("woff2");
|
||||
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
|
||||
}
|
||||
/* math */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: italic;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkenkaWzU.woff2) format("woff2");
|
||||
unicode-range:
|
||||
U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333,
|
||||
U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1,
|
||||
U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071,
|
||||
U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F,
|
||||
U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B,
|
||||
U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF,
|
||||
U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11,
|
||||
U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF;
|
||||
}
|
||||
/* symbols */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: italic;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkaHkaWzU.woff2) format("woff2");
|
||||
unicode-range:
|
||||
U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199,
|
||||
U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF,
|
||||
U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB,
|
||||
U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3,
|
||||
U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E,
|
||||
U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2,
|
||||
U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F,
|
||||
U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3,
|
||||
U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6,
|
||||
U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513,
|
||||
U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD,
|
||||
U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC,
|
||||
U+1F700-1F7FF, U+1F800-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB,
|
||||
U+1F8C0-1F8C1, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C,
|
||||
U+1FA80-1FA89, U+1FA8F-1FAC6, U+1FACE-1FADC, U+1FADF-1FAE9, U+1FAF0-1FAF8, U+1FB00-1FBFF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: italic;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkCXkaWzU.woff2) format("woff2");
|
||||
unicode-range:
|
||||
U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304,
|
||||
U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: italic;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkCHkaWzU.woff2) format("woff2");
|
||||
unicode-range:
|
||||
U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF,
|
||||
U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: italic;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkBnka.woff2) format("woff2");
|
||||
unicode-range:
|
||||
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F,
|
||||
U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3GUBGEe.woff2) format("woff2");
|
||||
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3iUBGEe.woff2) format("woff2");
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3CUBGEe.woff2) format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3-UBGEe.woff2) format("woff2");
|
||||
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
|
||||
}
|
||||
/* math */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMawCUBGEe.woff2) format("woff2");
|
||||
unicode-range:
|
||||
U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333,
|
||||
U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1,
|
||||
U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071,
|
||||
U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F,
|
||||
U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B,
|
||||
U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF,
|
||||
U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11,
|
||||
U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF;
|
||||
}
|
||||
/* symbols */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMaxKUBGEe.woff2) format("woff2");
|
||||
unicode-range:
|
||||
U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199,
|
||||
U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF,
|
||||
U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB,
|
||||
U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3,
|
||||
U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E,
|
||||
U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2,
|
||||
U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F,
|
||||
U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3,
|
||||
U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6,
|
||||
U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513,
|
||||
U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD,
|
||||
U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC,
|
||||
U+1F700-1F7FF, U+1F800-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB,
|
||||
U+1F8C0-1F8C1, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C,
|
||||
U+1FA80-1FA89, U+1FA8F-1FAC6, U+1FACE-1FADC, U+1FADF-1FAE9, U+1FAF0-1FAF8, U+1FB00-1FBFF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3OUBGEe.woff2) format("woff2");
|
||||
unicode-range:
|
||||
U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304,
|
||||
U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3KUBGEe.woff2) format("woff2");
|
||||
unicode-range:
|
||||
U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF,
|
||||
U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 100%;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3yUBA.woff2) format("woff2");
|
||||
unicode-range:
|
||||
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F,
|
||||
U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Roboto", sans-serif !important;
|
||||
}
|
||||
5
src/assets/css/main.css
Normal file
5
src/assets/css/main.css
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
@import "./tailwind.css";
|
||||
|
||||
@import "dolphin-components/dolphin-components.css";
|
||||
@import "./font.css";
|
||||
@import "./animation.css";
|
||||
46
src/assets/css/tailwind.css
Normal file
46
src/assets/css/tailwind.css
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
@import "tailwindcss";
|
||||
|
||||
@theme {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
|
||||
--color-modal: var(--card);
|
||||
--color-modal-foreground: var(--card-foreground);
|
||||
|
||||
--color-modal: var(--card);
|
||||
--color-modal-foreground: var(--card-foreground);
|
||||
|
||||
--color-popover: var(--popover);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
|
||||
--color-primary: var(--primary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
|
||||
--color-secondary: var(--secondary);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
|
||||
--color-muted: var(--muted);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
|
||||
--color-border: var(--border);
|
||||
--color-border-foreground: var(--border-foreground);
|
||||
--color-input: var(--input);
|
||||
--color-input-focus: var(--input-focus);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-scrollbar: var(--scrollbar);
|
||||
|
||||
--radius-default: var(--radius);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
*,
|
||||
::after,
|
||||
::before,
|
||||
::backdrop,
|
||||
::file-selector-button {
|
||||
border-color: var(--color-gray-200, currentColor);
|
||||
}
|
||||
}
|
||||
0
src/assets/ts/main.ts
Normal file
0
src/assets/ts/main.ts
Normal file
12
src/components/navigation/Footer.vue
Normal file
12
src/components/navigation/Footer.vue
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="absolute w-[100%] z-2 border-t border-gray-200 bg-white bottom-0 text-[13px] p-1 text-end px-2 h-[30px]"
|
||||
>
|
||||
<span style="font-family: "Raleway", sans-serif" class="font-bold">©</span>
|
||||
2025, Mavorion Systems. All rights reserved.
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
116
src/components/navigation/Navbar.vue
Normal file
116
src/components/navigation/Navbar.vue
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
<template>
|
||||
<nav class="header-container">
|
||||
<div class="px-[15px] flex justify-between items-center w-full h-full relative">
|
||||
<div class="">
|
||||
<img src="/img/Dolphin/dolphin-logo.png" alt="" class="w-32 my-auto" />
|
||||
</div>
|
||||
|
||||
<div class="relative select-none" id="modal-div-nav-profile">
|
||||
<div
|
||||
class="w-[32px] rounded-full text-white h-[32px] flex justify-center bg-primary cursor-pointer"
|
||||
@click="isUserMenuOpen = !isUserMenuOpen"
|
||||
>
|
||||
<span v-if="user.avatar" class="h-fit my-auto text-[16px]">
|
||||
<img
|
||||
:src="user.avatar"
|
||||
alt="Profile photo"
|
||||
class="w-[32px] h-[32px] object-cover rounded-full"
|
||||
/>
|
||||
</span>
|
||||
<span v-else class="h-fit my-auto text-[16px]">
|
||||
{{ getNameInitials(user.full_name || user.username) }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="isUserMenuOpen"
|
||||
class="absolute bg-white right-0 w-[200px] border shadow-sm"
|
||||
tabindex="0"
|
||||
ref="userProfileMenu"
|
||||
>
|
||||
<div>
|
||||
<div class="px-[15px] py-[5px] border-b">
|
||||
<div class="text-[12px] font-bold">Account</div>
|
||||
<div class="flex gap-[5px]">
|
||||
<div
|
||||
class="text-white w-[24px] h-[24px] rounded-full flex justify-center item-center bg-primary"
|
||||
@click="action('profile')"
|
||||
>
|
||||
<span v-if="user.avatar" class="h-fit my-auto text-[14px]">
|
||||
<img
|
||||
:src="user.avatar"
|
||||
alt="Profile photo"
|
||||
class="w-[24px] h-[24px] object-cover rounded-full"
|
||||
/>
|
||||
</span>
|
||||
<span v-else class="h-fit my-auto text-[12px]">
|
||||
{{ getNameInitials(user.full_name || user.username) }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<div>{{ user.full_name || user.username }}</div>
|
||||
<div class="text-[12px] text-secondary-foreground">{{ user.email }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="px-[15px] py-[5px] hover:bg-secondary cursor-pointer text-red-500"
|
||||
@click="action('logout')"
|
||||
>
|
||||
Logout
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { useAuth } from "@/stores/User/Auth";
|
||||
import { useUser } from "@/stores/User/User";
|
||||
|
||||
const authStore = useAuth();
|
||||
const userStore = useUser();
|
||||
|
||||
const { getUser: user } = storeToRefs(userStore);
|
||||
|
||||
const isUserMenuOpen = ref(false);
|
||||
|
||||
const getNameInitials = (name: string): string => {
|
||||
if (!name) return '';
|
||||
|
||||
const names = name.trim().split(' ');
|
||||
if (names.length === 1) {
|
||||
return names[0].charAt(0).toUpperCase();
|
||||
}
|
||||
|
||||
return (names[0].charAt(0) + names[names.length - 1].charAt(0)).toUpperCase();
|
||||
};
|
||||
|
||||
function handleDocumentClick(event: any) {
|
||||
const element = document.getElementById("modal-div-nav-profile");
|
||||
if (isUserMenuOpen.value && !(event.target == element || element?.contains(event.target))) {
|
||||
isUserMenuOpen.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
document.addEventListener("click", handleDocumentClick);
|
||||
});
|
||||
|
||||
onUnmounted(async () => {
|
||||
document.removeEventListener("click", handleDocumentClick);
|
||||
});
|
||||
|
||||
const action = (type: string) => {
|
||||
switch (type) {
|
||||
case "logout":
|
||||
authStore.logout();
|
||||
break;
|
||||
}
|
||||
|
||||
isUserMenuOpen.value = false;
|
||||
};
|
||||
</script>
|
||||
195
src/components/navigation/Sidebar.vue
Normal file
195
src/components/navigation/Sidebar.vue
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
<template>
|
||||
<div class="sidebar-container">
|
||||
<aside
|
||||
class="fixed left-0 z-50 w-[45px] h-screen transition-transform border-r select-none group hover:bg-secondary-10 cursor-pointer"
|
||||
v-if="!isSidebarOpen"
|
||||
@click="toggleSideBar"
|
||||
>
|
||||
<svg
|
||||
data-v-3005ba44=""
|
||||
class="mt-[15px] group-hover:fill-secondary-600 fill-secondary-400 mx-auto"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
width="20px"
|
||||
height="20px"
|
||||
data-prefix="fas"
|
||||
data-icon="bars"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 448 512"
|
||||
data-fa-i2svg=""
|
||||
>
|
||||
<path
|
||||
d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"
|
||||
></path>
|
||||
</svg>
|
||||
</aside>
|
||||
<aside
|
||||
id="logo-sidebar"
|
||||
class="sidebar fixed left-0 z-1 w-[225px] h-screen transition-transform border-r border-gray-200 overflow-y-scroll overflow-x-hidden"
|
||||
:class="isSidebarOpen ? '' : '-translate-x-full'"
|
||||
aria-label="Sidebar"
|
||||
v-hide-scrollbar
|
||||
>
|
||||
<div class="sidebar-items pb-[95px]">
|
||||
<div class="absolute right-4">
|
||||
<svg
|
||||
@click="toggleSideBar"
|
||||
class="stroke-secondary-700 hover:stroke-primary-700 duration-200 cursor-pointer"
|
||||
width="25px"
|
||||
height="25px"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g id="SVGRepo_iconCarrier">
|
||||
<path
|
||||
d="M6 12H18M6 12L11 7M6 12L11 17"
|
||||
stroke-width="1.584"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div v-for="(item, index) in sidebarItems">
|
||||
<div
|
||||
class="sidebar-header"
|
||||
v-if="!item.to && !item.children && (item.isVisible != undefined ? item.isVisible : true)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<RouterLink
|
||||
:to="item.to"
|
||||
v-if="item.to && !item.children && (item.isVisible != undefined ? item.isVisible : true)"
|
||||
class="sidebar-default"
|
||||
:class="isActive(item) ? 'sidebar-item-active' : ''"
|
||||
@click="closeAllDropdowns()"
|
||||
>
|
||||
<div>
|
||||
<Icons :name="item.icon" size="20" />
|
||||
</div>
|
||||
<span>{{ item.label }}</span>
|
||||
</RouterLink>
|
||||
<div
|
||||
v-if="item.children && !item.to && (item.isVisible != undefined ? item.isVisible : true)"
|
||||
class="sidebar-dropdown"
|
||||
:class="activeDropdown == index ? 'sidebar-item-open' : ''"
|
||||
>
|
||||
<div class="sidebar-dropdown-header" @click="toggleDropdown(index)">
|
||||
<div>
|
||||
<Icons :name="item.icon" size="20" />
|
||||
</div>
|
||||
<span>{{ item.label }}</span>
|
||||
<div class="sidebar-chevron">
|
||||
<Icons name="ChevronRight" size="14" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="sidebar-dropdown-items"
|
||||
v-if="activeDropdown == index && isSidebarOpen"
|
||||
v-animate-dropdown
|
||||
>
|
||||
<div class="sidebar-dropdown-item" v-for="childitem in item.children">
|
||||
<RouterLink
|
||||
:to="childitem.to"
|
||||
:class="isActive(childitem) ? 'sidebar-item-active' : ''"
|
||||
v-if="childitem.isVisible != undefined ? childitem.isVisible : true"
|
||||
>
|
||||
<span>{{ childitem.label }}</span>
|
||||
</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, type PropType, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import type { SidebarItem } from "@/dtos/common/Sidebar";
|
||||
import { useSidebar } from "@/stores/App/App";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { watch, nextTick } from "vue";
|
||||
const router = useRouter();
|
||||
|
||||
const emit = defineEmits(["toggleSideBar"]);
|
||||
|
||||
const sidebarStore = useSidebar();
|
||||
const { isSidebarOpen } = storeToRefs(sidebarStore);
|
||||
|
||||
const props = defineProps({
|
||||
sidebarItems: {
|
||||
type: Array as PropType<SidebarItem[]>,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const toggleSideBar = () => {
|
||||
sidebarStore.setSidebarStatus(!isSidebarOpen.value);
|
||||
};
|
||||
|
||||
const activeDropdown = ref(-1);
|
||||
|
||||
const closeAllDropdowns = () => {
|
||||
activeDropdown.value = -1;
|
||||
};
|
||||
|
||||
const toggleDropdown = (val: number) => {
|
||||
if (activeDropdown.value == val) {
|
||||
activeDropdown.value = -1;
|
||||
} else {
|
||||
activeDropdown.value = val;
|
||||
}
|
||||
};
|
||||
|
||||
const isActive = (item: SidebarItem) => {
|
||||
if (item.to == router.currentRoute.value.path) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
checkDropDown();
|
||||
});
|
||||
|
||||
const checkDropDown = () => {
|
||||
if (props.sidebarItems) {
|
||||
props.sidebarItems.forEach((item) => {
|
||||
if (item.children && !item.to && (item.isVisible != undefined ? item.isVisible : true)) {
|
||||
item.children.forEach((child) => {
|
||||
if (
|
||||
child.to == router.currentRoute.value.path &&
|
||||
(child.isVisible != undefined ? child.isVisible : true)
|
||||
) {
|
||||
toggleDropdown(props.sidebarItems.indexOf(item));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
watch(isSidebarOpen, (newVal) => {
|
||||
if (newVal) {
|
||||
nextTick(() => {
|
||||
const sidebar = document.getElementById("logo-sidebar");
|
||||
sidebar?.dispatchEvent(new Event("scroll"));
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#logo-sidebar {
|
||||
scrollbar-width: thick;
|
||||
}
|
||||
|
||||
#logo-sidebar::-webkit-scrollbar {
|
||||
width: 10px !important;
|
||||
}
|
||||
</style>
|
||||
32
src/layouts/AuthLayout.vue
Normal file
32
src/layouts/AuthLayout.vue
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<template>
|
||||
<div class="app-container" :class="isSidebarOpen ? 'sidebar-open' : 'sidebar-close'">
|
||||
<Navbar></Navbar>
|
||||
<div class="body-container">
|
||||
<Sidebar
|
||||
:sidebarItems="SidebarItems"
|
||||
@notVisible="sidebarVisible = false"
|
||||
@visible="sidebarVisible = true"
|
||||
></Sidebar>
|
||||
<div class="main-container" :class="sidebarVisible ? '' : 'pl-0'">
|
||||
<div class="relative">
|
||||
<RouterView />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer></Footer>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Sidebar from "@/components/navigation/Sidebar.vue";
|
||||
import Navbar from "@/components/navigation/Navbar.vue";
|
||||
import { ref, computed } from "vue";
|
||||
import { useSidebarItems } from "@/utils/setup/SidebarItems";
|
||||
import Footer from "@/components/navigation/Footer.vue";
|
||||
import { useSidebar } from "@/stores/App/App";
|
||||
import { storeToRefs } from "pinia";
|
||||
|
||||
const SidebarItems = computed(() => useSidebarItems());
|
||||
const sidebarStore = useSidebar();
|
||||
const { isSidebarOpen } = storeToRefs(sidebarStore);
|
||||
const sidebarVisible = ref(true);
|
||||
</script>
|
||||
7
src/router/authChildren.ts
Normal file
7
src/router/authChildren.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import type { RouteRecordRaw } from "vue-router";
|
||||
// import { PERMISSIONS } from "@/constants/permissions";
|
||||
|
||||
const authChildren: Array<RouteRecordRaw> = [
|
||||
];
|
||||
|
||||
export default authChildren;
|
||||
|
|
@ -1,8 +1,35 @@
|
|||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import authChildren from "./authChildren";
|
||||
// import { PERMISSIONS } from "@/constants/permissions";
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: [],
|
||||
})
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
{
|
||||
path: "/",
|
||||
name: "authLayout",
|
||||
component: () => import("@/layouts/AuthLayout.vue"),
|
||||
meta: {
|
||||
requireAuth: true,
|
||||
},
|
||||
children: authChildren,
|
||||
},
|
||||
// {
|
||||
// path: "/login",
|
||||
// name: "login",
|
||||
// component: () => import("@/views/Auth/Login.vue"),
|
||||
// },
|
||||
// {
|
||||
// path: "/:pathMatch(.*)*",
|
||||
// name: "404",
|
||||
// component: () => import("@/views/404.vue"),
|
||||
// },
|
||||
// {
|
||||
// path: "/403",
|
||||
// name: "403",
|
||||
// component: () => import("@/views/403.vue"),
|
||||
// },
|
||||
],
|
||||
});
|
||||
|
||||
export default router
|
||||
export default router;
|
||||
|
|
|
|||
|
|
@ -3,16 +3,23 @@ import { fileURLToPath, URL } from 'node:url'
|
|||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
base: '/',
|
||||
plugins: [
|
||||
vue(),
|
||||
vueDevTools(),
|
||||
tailwindcss(),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
},
|
||||
},
|
||||
server: {
|
||||
port: 3000,
|
||||
hmr: true,
|
||||
},
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user