first commit
This commit is contained in:
39
.gitignore
vendored
Normal file
39
.gitignore
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
coverage
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Cypress
|
||||||
|
/cypress/videos/
|
||||||
|
/cypress/screenshots/
|
||||||
|
|
||||||
|
# Vitest
|
||||||
|
__screenshots__/
|
||||||
|
|
||||||
|
# Vite
|
||||||
|
*.timestamp-*-*.mjs
|
||||||
3
.vscode/extensions.json
vendored
Normal file
3
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"recommendations": ["Vue.volar"]
|
||||||
|
}
|
||||||
25
index.html
Normal file
25
index.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="icon" href="/favicon.ico">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;700&display=swap">
|
||||||
|
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css" rel="stylesheet"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Sonoma - Free Lossless Audio Streaming</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
<script
|
||||||
|
src="https://code.jquery.com/jquery-3.6.0.min.js"
|
||||||
|
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
|
||||||
|
crossorigin="anonymous">
|
||||||
|
</script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
3216
package-lock.json
generated
Normal file
3216
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
31
package.json
Normal file
31
package.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "sonoma-site",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "run-p type-check \"build-only {@}\" --",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"build-only": "vite build",
|
||||||
|
"type-check": "vue-tsc --build"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"vue": "^3.5.27",
|
||||||
|
"vue-router": "^5.0.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@tsconfig/node24": "^24.0.4",
|
||||||
|
"@types/node": "^24.10.9",
|
||||||
|
"@vitejs/plugin-vue": "^6.0.3",
|
||||||
|
"@vue/tsconfig": "^0.8.1",
|
||||||
|
"npm-run-all2": "^8.0.4",
|
||||||
|
"typescript": "~5.9.3",
|
||||||
|
"vite": "^7.3.1",
|
||||||
|
"vite-plugin-vue-devtools": "^8.0.5",
|
||||||
|
"vue-tsc": "^3.2.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 261 KiB |
BIN
public/icon.png
Normal file
BIN
public/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 173 KiB |
51
src/App.vue
Normal file
51
src/App.vue
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<header>
|
||||||
|
<div class="logo"><a href="/"><img src="/public/icon.png"></a></div>
|
||||||
|
<nav>
|
||||||
|
<RouterLink to='/'>Главная</RouterLink>
|
||||||
|
<a href="https://open.sonoma.su">Слушать</a>
|
||||||
|
<a onclick="toastr.error('В разработке')">Для исполнителей</a>
|
||||||
|
</nav>
|
||||||
|
<button class="theme-toggle" @click="toggleTheme">
|
||||||
|
<i :class="isLightTheme ? 'fas fa-moon' : 'fas fa-sun'"></i>
|
||||||
|
</button>
|
||||||
|
</header>
|
||||||
|
<RouterView />
|
||||||
|
<footer>
|
||||||
|
<div class="footer-top">
|
||||||
|
<div class="footer-links">
|
||||||
|
<a href="https://sonoma.su">Создано группой Sonoma</a>
|
||||||
|
<a>Обратная связь - support@sonoma.su</a>
|
||||||
|
</div>
|
||||||
|
<div class="footer-icons">
|
||||||
|
<a href="https://git.sonoma.su/Sonoma/sonoma-site"><i class="fab fa-github"></i></a>
|
||||||
|
<a href="https://t.me/saddydead"><i class="fab fa-telegram"></i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer-bottom">
|
||||||
|
<p>Copyright ©2026 Sonoma</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
data(): { isLightTheme: boolean } {
|
||||||
|
return {
|
||||||
|
isLightTheme: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleTheme(): void {
|
||||||
|
this.isLightTheme = !this.isLightTheme;
|
||||||
|
if (this.isLightTheme) {
|
||||||
|
document.body.classList.add('light-theme');
|
||||||
|
} else {
|
||||||
|
document.body.classList.remove('light-theme');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
312
src/assets/main.css
Normal file
312
src/assets/main.css
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: 'Inter', sans-serif;
|
||||||
|
background: linear-gradient(180deg, #2b1d3a, #000);
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
transition: background 0.3s, color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.light-theme {
|
||||||
|
background: linear-gradient(180deg, #f0f0f0, #ffffff);
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px;
|
||||||
|
background: rgba(0, 0, 0, 0.8);
|
||||||
|
transition: background 0.3s;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.light-theme header {
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a {
|
||||||
|
color: #fff;
|
||||||
|
margin: 0 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
details a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #a18cd1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.r1 {
|
||||||
|
text-decoration: none;
|
||||||
|
background: linear-gradient(90deg, #a18cd1, #fbc2eb);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
summary {
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.light-theme nav a {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
font-size: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-title {
|
||||||
|
margin-top: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-family: 'Manrope', sans serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-family: 'Manrope', sans serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-title h1 {
|
||||||
|
font-family: 'Manrope', sans serif;
|
||||||
|
font-size: 64px;
|
||||||
|
background: linear-gradient(90deg, #a18cd1, #fbc2eb);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-title button {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 15px 30px;
|
||||||
|
font-size: 18px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 30px;
|
||||||
|
background: linear-gradient(90deg, #a18cd1, #fbc2eb);
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing {
|
||||||
|
margin: 100px auto;
|
||||||
|
max-width: 1000px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing h2 {
|
||||||
|
font-family: 'Manrope', sans serif;
|
||||||
|
font-size: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artists {
|
||||||
|
margin: 100px auto;
|
||||||
|
max-width: 1000px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artists h2 {
|
||||||
|
font-family: 'Manrope', sans serif;
|
||||||
|
font-size: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background: #2b1d3a;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 30px;
|
||||||
|
width: 250px;
|
||||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
|
||||||
|
transition: background 0.3s, color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.light-theme .card {
|
||||||
|
background: #fff;
|
||||||
|
color: #000;
|
||||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card h3 {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card p {
|
||||||
|
font-size: 18px;
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card button {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-size: 16px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 20px;
|
||||||
|
background: linear-gradient(90deg, #a18cd1, #fbc2eb);
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artist {
|
||||||
|
background: #2b1d3a;
|
||||||
|
border-radius: 200px;
|
||||||
|
padding: 30px;
|
||||||
|
width: 250px;
|
||||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
|
||||||
|
transition: background 0.3s, color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.light-theme .artist {
|
||||||
|
background: #fff;
|
||||||
|
color: #000;
|
||||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.artist h3 {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artist p {
|
||||||
|
font-size: 18px;
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artist button {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-size: 16px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 20px;
|
||||||
|
background: linear-gradient(90deg, #a18cd1, #fbc2eb);
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight {
|
||||||
|
background: #fff;
|
||||||
|
color: #2b1d3a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo img {
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
footer {
|
||||||
|
background: #0e0e0e;
|
||||||
|
color: #fff;
|
||||||
|
padding: 40px 100px;
|
||||||
|
font-family: 'Manrope', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-top {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
border-bottom: 1px solid #444;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-links {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-links a {
|
||||||
|
color: #aaa;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-links a:hover {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-icons a {
|
||||||
|
margin-right: 15px;
|
||||||
|
color: #aaa;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-icons a:hover {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-bottom {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-bottom p {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.footer-top {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-links {
|
||||||
|
justify-content: center;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-icons {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticker {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
pointer-events: none;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ticker-track {
|
||||||
|
display: inline-flex;
|
||||||
|
gap: 64px;
|
||||||
|
padding-left: 100%;
|
||||||
|
animation: scroll 20s linear infinite;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ticker-track span {
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@keyframes scroll {
|
||||||
|
from {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
101
src/components/Main.vue
Normal file
101
src/components/Main.vue
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<section class="main-title">
|
||||||
|
<h1>Sonoma Hi-Res</h1>
|
||||||
|
<p>Полностью бесплатный стриминговый сервис для прослушивания FLAC, Lossless и Hi-Res! <br> До 24bit/192kHz</p>
|
||||||
|
<button @click="$router.push('register')">Начать</button>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="pricing">
|
||||||
|
<h2>Наши преимущества</h2>
|
||||||
|
<p>Чем же мы отличаемся от конкурентов?</p>
|
||||||
|
<div class="options">
|
||||||
|
<div class="card">
|
||||||
|
<h3>Для всех устройств</h3>
|
||||||
|
<p>У нас есть приложения для каждого</p>
|
||||||
|
<p>Windows, Mac, Linux,</p>
|
||||||
|
<p>Web, Android и iOS</p>
|
||||||
|
</div>
|
||||||
|
<div class="card highlight">
|
||||||
|
<h3>Бесплатно</h3>
|
||||||
|
<p>Сервис полностью бесплатный</p>
|
||||||
|
<p>До 24bit/192kHz</p>
|
||||||
|
<p>Все форматы, включая FLAC, Lossless и Hi-Res</p>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<h3>Поддержка исполнителей</h3>
|
||||||
|
<p>Наш сервис строится на музыке,</p>
|
||||||
|
<p>которую может загрузить любой желающий!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="options">
|
||||||
|
<div class="card highlight">
|
||||||
|
<h3>От таких же как вы</h3>
|
||||||
|
<p>Мы тоже любим музыку в хорошем качестве и бесплатно</p>
|
||||||
|
<p>Также мы знаем, как сложно найти лейбл маленькому артисту</p>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<h3>Open Source</h3>
|
||||||
|
<p>Весь исходный код сервиса открыт</p>
|
||||||
|
<p>Любой желающий может на него посмотреть</p>
|
||||||
|
<p>MIT License</p>
|
||||||
|
</div>
|
||||||
|
<div class="card highlight">
|
||||||
|
<h3>Сервера в России</h3>
|
||||||
|
<p>Не будет проблем с задержкой или лагами</p>
|
||||||
|
<p>Сервис сделан русскими людьми</p>
|
||||||
|
<p>Поддержка 24/7</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="pricing">
|
||||||
|
<h2>Варианты подписок</h2>
|
||||||
|
<p>Все возможные варианты подписок</p>
|
||||||
|
<div class="options">
|
||||||
|
<div class="card">
|
||||||
|
<h3>Sonoma Artist</h3>
|
||||||
|
<p>Специально для исполнителей</p>
|
||||||
|
<p>Мы ищем исполнителей,</p>
|
||||||
|
<p>Но вы можете сами оставить нам заявку!</p>
|
||||||
|
<button onclick="toastr.error('В разработке')">Связаться</button>
|
||||||
|
</div>
|
||||||
|
<div class="card highlight">
|
||||||
|
<h3>Sonoma Plus</h3>
|
||||||
|
<p>Free</p>
|
||||||
|
<p>Доступ к сервису</p>
|
||||||
|
<p>24bit/192kHz</p>
|
||||||
|
<p>Все форматы, включая FLAC, Lossless и Hi-Res</p>
|
||||||
|
<button onclick="location.href='https://discord.gg/sEqEEchsQW'">Регистрация</button>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<h3>Sonoma Staff</h3>
|
||||||
|
<p>Хотите присоединиться к разработке?</p>
|
||||||
|
<p>Сервис разрабатывается одним человеком</p>
|
||||||
|
<p>Будем рады в поддержке!</p>
|
||||||
|
<button onclick="location.href='https://t.me/saddydead'">Связаться</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="artists">
|
||||||
|
<h2>Нас выбирают</h2>
|
||||||
|
<p>Посмотрите артистов, которые выбрали нас</p>
|
||||||
|
<div class="ticker">
|
||||||
|
<div class="ticker-track">
|
||||||
|
<span>SaddyDEAD</span>
|
||||||
|
<span>ARTIST</span>
|
||||||
|
<span>ARTIST</span>
|
||||||
|
<span>ARTIST</span>
|
||||||
|
<span>ARTIST</span>
|
||||||
|
<span>ARTIST</span>
|
||||||
|
<span>ARTIST</span>
|
||||||
|
<span>ARTIST</span>
|
||||||
|
<span>ARTIST</span>
|
||||||
|
<span>ARTIST</span>
|
||||||
|
<span>ARTIST</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
20
src/main.ts
Normal file
20
src/main.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import './assets/main.css'
|
||||||
|
|
||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
|
||||||
|
import { createMemoryHistory, createRouter } from 'vue-router'
|
||||||
|
|
||||||
|
import Main from './components/Main.vue'
|
||||||
|
|
||||||
|
|
||||||
|
const routes = [
|
||||||
|
{ path: '/', component: Main }
|
||||||
|
]
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: createMemoryHistory(),
|
||||||
|
routes,
|
||||||
|
})
|
||||||
|
|
||||||
|
createApp(App).use(router).mount('#app')
|
||||||
12
tsconfig.app.json
Normal file
12
tsconfig.app.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||||
|
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
|
||||||
|
"exclude": ["src/**/__tests__/*"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
tsconfig.json
Normal file
11
tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.node.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.app.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
19
tsconfig.node.json
Normal file
19
tsconfig.node.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"extends": "@tsconfig/node24/tsconfig.json",
|
||||||
|
"include": [
|
||||||
|
"vite.config.*",
|
||||||
|
"vitest.config.*",
|
||||||
|
"cypress.config.*",
|
||||||
|
"nightwatch.conf.*",
|
||||||
|
"playwright.config.*",
|
||||||
|
"eslint.config.*"
|
||||||
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"noEmit": true,
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"types": ["node"]
|
||||||
|
}
|
||||||
|
}
|
||||||
18
vite.config.ts
Normal file
18
vite.config.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { fileURLToPath, URL } from 'node:url'
|
||||||
|
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
vue(),
|
||||||
|
vueDevTools(),
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user