initial commit
This commit is contained in:
parent
902ec501b0
commit
d33be0643b
113
package-lock.json
generated
113
package-lock.json
generated
@ -8,10 +8,10 @@
|
||||
"name": "test-task-medods",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@vuelidate/core": "^2.0.3",
|
||||
"@vuelidate/validators": "^2.0.4",
|
||||
"@yandex/ymaps3-types": "^0.0.21",
|
||||
"vue": "^3.4.19",
|
||||
"vue-router": "^4.3.0"
|
||||
"vue-router": "^4.3.0",
|
||||
"vue-yandex-maps": "^2.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^2.6.4",
|
||||
@ -1508,86 +1508,23 @@
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz",
|
||||
"integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw=="
|
||||
},
|
||||
"node_modules/@vuelidate/core": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@vuelidate/core/-/core-2.0.3.tgz",
|
||||
"integrity": "sha512-AN6l7KF7+mEfyWG0doT96z+47ljwPpZfi9/JrNMkOGLFv27XVZvKzRLXlmDPQjPl/wOB1GNnHuc54jlCLRNqGA==",
|
||||
"dependencies": {
|
||||
"vue-demi": "^0.13.11"
|
||||
},
|
||||
"node_modules/@yandex/ymaps3-types": {
|
||||
"version": "0.0.21",
|
||||
"resolved": "https://registry.npmjs.org/@yandex/ymaps3-types/-/ymaps3-types-0.0.21.tgz",
|
||||
"integrity": "sha512-mMKDhzHdV+4ZkzrN2oKzRXEHfCtS3/PLjzWUG2Tp5qsBWszViruk4gng+c/ORthztooYRgqB2+U5syNHDPc0Kw==",
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.0.0-rc.1",
|
||||
"vue": "^2.0.0 || >=3.0.0"
|
||||
"@types/react": "16-18",
|
||||
"@types/react-dom": "16-18",
|
||||
"@vue/runtime-core": "3"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vuelidate/core/node_modules/vue-demi": {
|
||||
"version": "0.13.11",
|
||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
|
||||
"integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.0.0-rc.1",
|
||||
"vue": "^3.0.0-0 || ^2.6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vuelidate/validators": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@vuelidate/validators/-/validators-2.0.4.tgz",
|
||||
"integrity": "sha512-odTxtUZ2JpwwiQ10t0QWYJkkYrfd0SyFYhdHH44QQ1jDatlZgTh/KRzrWVmn/ib9Gq7H4hFD4e8ahoo5YlUlDw==",
|
||||
"dependencies": {
|
||||
"vue-demi": "^0.13.11"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.0.0-rc.1",
|
||||
"vue": "^2.0.0 || >=3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vuelidate/validators/node_modules/vue-demi": {
|
||||
"version": "0.13.11",
|
||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
|
||||
"integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.0.0-rc.1",
|
||||
"vue": "^3.0.0-0 || ^2.6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"@vue/runtime-core": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
@ -4950,6 +4887,30 @@
|
||||
"vue": "^3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-yandex-maps": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-yandex-maps/-/vue-yandex-maps-2.0.1.tgz",
|
||||
"integrity": "sha512-tLP+3YZKazLNWsoYF2tMZCM4RCAUMspz5FOk2VnlPWaDFHi71PtHo8dfhTlf5Guy9YP2i11YjZGJfBfSUsEU4g==",
|
||||
"dependencies": {
|
||||
"@yandex/ymaps3-types": ">=0.0.21"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": ">=1",
|
||||
"nuxt": "^2.16 || ^3",
|
||||
"vue": "^2.7 || ^3.3"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"optional": true
|
||||
},
|
||||
"nuxt": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
14
package.json
14
package.json
@ -1,18 +1,20 @@
|
||||
{
|
||||
"name": "test-task-medods",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vuelidate/core": "^2.0.3",
|
||||
"@vuelidate/validators": "^2.0.4",
|
||||
"@yandex/ymaps3-types": "^0.0.21",
|
||||
"vue": "^3.4.19",
|
||||
"vue-router": "^4.3.0"
|
||||
"vue-router": "^4.3.0",
|
||||
"vue-yandex-maps": "^2.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^2.6.4",
|
||||
|
BIN
public/shop.png
Normal file
BIN
public/shop.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 261 KiB |
@ -51,7 +51,6 @@ body {
|
||||
body {
|
||||
background: black;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
overflow: hidden;
|
||||
color: white;
|
||||
}
|
||||
|
||||
@ -77,7 +76,7 @@ button:hover {
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 800px;
|
||||
max-width: 1400px;
|
||||
width: 100%;
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"sourceRoot":"","sources":["fonts.scss","style.scss","normalize.scss"],"names":[],"mappings":"AAAQ;AAER;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AC3CF;AAAA;EAEE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EAEA;;;ACtCF;AAEA;AAAA;AAGA;AAAA;AAAA;AAAA;AAKA;EACE;EACA;;;AAGF;AAAA;AAGA;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAAA;AAUA;AAAA;AAGA;AAAA;AAAA;AAAA;AAKA;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;AAKA;EACE;EACA;;;AAGF;AAAA;AAGA;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAAA;AAKA;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;AAIA;AAAA;EAEE;;;AAGF;AAAA;AAAA;AAAA;AAKA;AAAA;AAAA;EAGE;EACA;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAAA;AAKA;AAAA;EAEE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAAA;AAGA;AAAA;AAAA;AAIA;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;AAAA;AAGA;AAAA;AAAA;AAAA;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;AAKA;AAAA,QACQ;EACN;;;AAGF;AAAA;AAAA;AAAA;AAKA;AAAA,SACS;EACP;;;AAGF;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;EAIE;;;AAGF;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;EAIE;EACA;;;AAGF;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;EAIE;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAAA;AAKA;AAAA;EAEE;EACA;;;AAGF;AAAA;AAAA;AAIA;AAAA;EAEE;;;AAGF;AAAA;AAAA;AAAA;AAKA;EACE;EACA;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAAA;AAKA;EACE;EACA;;;AAGF;AAAA;AAGA;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAGA;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAIA;EACE","file":"index.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["fonts.scss","style.scss","normalize.scss"],"names":[],"mappings":"AAAQ;AAER;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AC3CF;AAAA;EAEE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EAEA;;;ACrCF;AAEA;AAAA;AAGA;AAAA;AAAA;AAAA;AAKA;EACE;EACA;;;AAGF;AAAA;AAGA;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAAA;AAUA;AAAA;AAGA;AAAA;AAAA;AAAA;AAKA;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;AAKA;EACE;EACA;;;AAGF;AAAA;AAGA;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAAA;AAKA;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;AAIA;AAAA;EAEE;;;AAGF;AAAA;AAAA;AAAA;AAKA;AAAA;AAAA;EAGE;EACA;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAAA;AAKA;AAAA;EAEE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAAA;AAGA;AAAA;AAAA;AAIA;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;AAAA;AAGA;AAAA;AAAA;AAAA;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;AAKA;AAAA,QACQ;EACN;;;AAGF;AAAA;AAAA;AAAA;AAKA;AAAA,SACS;EACP;;;AAGF;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;EAIE;;;AAGF;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;EAIE;EACA;;;AAGF;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;EAIE;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAAA;AAKA;AAAA;EAEE;EACA;;;AAGF;AAAA;AAAA;AAIA;AAAA;EAEE;;;AAGF;AAAA;AAAA;AAAA;AAKA;EACE;EACA;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAAA;AAKA;EACE;EACA;;;AAGF;AAAA;AAGA;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAGA;AAAA;AAAA;AAIA;EACE;;;AAGF;AAAA;AAAA;AAIA;EACE","file":"index.css"}
|
@ -6,7 +6,6 @@ body {
|
||||
body {
|
||||
background: black;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
overflow: hidden;
|
||||
color: white;
|
||||
}
|
||||
|
||||
@ -33,7 +32,7 @@ button {
|
||||
}
|
||||
|
||||
.container{
|
||||
max-width: 800px;
|
||||
max-width: 1400px;
|
||||
width: 100%;
|
||||
|
||||
margin-inline: auto;
|
||||
|
@ -1,58 +0,0 @@
|
||||
<template>
|
||||
<button
|
||||
class="btn" :class="[{ btn_icon: icon }, { btn_medium: medium }]"
|
||||
@click="clickOnButton()"
|
||||
>
|
||||
<slot v-if="icon" name="icon">
|
||||
<Component :is="icon" />
|
||||
</slot>
|
||||
|
||||
<slot v-if="!icon" />
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
icon: {},
|
||||
medium: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
const emit = defineEmits(['click'])
|
||||
|
||||
function clickOnButton() {
|
||||
emit('click')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.btn {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
background: white;
|
||||
color: black;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: .2s;
|
||||
|
||||
&_icon {
|
||||
padding: 10px;
|
||||
background-color: #F4F5FD;
|
||||
border-radius: 8px;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
&_medium {
|
||||
width: 140px;
|
||||
height: 42px;
|
||||
background-color: #FFE27A;
|
||||
border-radius: 7px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,87 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<input
|
||||
class='checkbox'
|
||||
type="checkbox"
|
||||
:id="id"
|
||||
:checked="checked"
|
||||
@input="handleClick($event)">
|
||||
<label :for="id">{{ text }}</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const emits = defineEmits(['update:checked'])
|
||||
const props = defineProps({
|
||||
checked: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
})
|
||||
const handleClick = (event) => {
|
||||
emits('update:checked', event.target.checked)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.checkbox {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
|
||||
& + label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
& + label::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
border: 1px solid #adb5bd;
|
||||
border-radius: 6px;
|
||||
margin-right: 10px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 50% 50%;
|
||||
}
|
||||
|
||||
&:checked + label::before {
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e");
|
||||
}
|
||||
|
||||
&:not(:disabled):not(:checked) + label:hover::before {
|
||||
border-color: var(--primary-hover);
|
||||
}
|
||||
|
||||
&:not(:disabled):active + label::before {
|
||||
background-color: var(--primary);
|
||||
border: 1px solid #ECEBED;
|
||||
}
|
||||
|
||||
&:focus + label::before {
|
||||
box-shadow: 0 7px 20px rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
|
||||
&:focus:not(:checked) + label::before {
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
&:disabled + label::before {
|
||||
background-color: #e9ecef;
|
||||
border: 1px solid #ECEBED;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,84 +0,0 @@
|
||||
<template>
|
||||
<label
|
||||
class="app-input"
|
||||
:style="{width: width}"
|
||||
>
|
||||
<div class="app-input__title">{{ title }}</div>
|
||||
<input
|
||||
:placeholder=placeholder
|
||||
:value="value"
|
||||
@input="updateValue"
|
||||
>
|
||||
<div
|
||||
class="app-input__warning"
|
||||
v-for="element of error"
|
||||
:key="element.$uid">
|
||||
<div class="form-error__message">{{ element.$message }}</div>
|
||||
</div>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const emit = defineEmits(['update:value'])
|
||||
const props = defineProps({
|
||||
error: {
|
||||
type: Array,
|
||||
default: ''
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '300px'
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
warning: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
const updateValue = (e) => {
|
||||
emit('update:value', e.target.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-input {
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
&__warning {
|
||||
color: red;
|
||||
margin-top: 5px;
|
||||
|
||||
input {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -1,41 +0,0 @@
|
||||
<template>
|
||||
<label class="app-select">
|
||||
<div>{{ title }}</div>
|
||||
<select class="select">
|
||||
<option v-for="item in items" :key="item.id">
|
||||
{{ item }}
|
||||
</option>
|
||||
</select>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
items: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.app-select {
|
||||
width: 300px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
.select {
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
height: 45px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
107
src/components/custom-map.vue
Normal file
107
src/components/custom-map.vue
Normal file
@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<YandexMap
|
||||
:settings="{ ...mapParameters, theme }"
|
||||
width="1270px"
|
||||
height="500px"
|
||||
>
|
||||
<YandexMapCartesianProjection
|
||||
:bounds="[
|
||||
[-PIC_WIDTH / 2, PIC_HEIGHT / 2 - worldSize],
|
||||
[worldSize - PIC_WIDTH / 2, PIC_HEIGHT / 2],
|
||||
]"
|
||||
/>
|
||||
|
||||
<YandexMapTileDataSource :settings="dataSourceProps" />
|
||||
<YandexMapLayer :settings="layerProps" />
|
||||
<YandexMapDefaultFeaturesLayer />
|
||||
<YandexMapDefaultMarker :settings="{ coordinates: [0, 0] }" />
|
||||
<YandexMapDefaultMarker :settings="{ coordinates: [600, 0] }" />
|
||||
<YandexMapDefaultMarker :settings="{ coordinates: [0, 600] }" />
|
||||
</YandexMap>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
YandexMap,
|
||||
YandexMapCartesianProjection,
|
||||
YandexMapDefaultFeaturesLayer,
|
||||
YandexMapDefaultMarker,
|
||||
YandexMapLayer,
|
||||
YandexMapTileDataSource,
|
||||
} from 'vue-yandex-maps'
|
||||
|
||||
import type {
|
||||
LngLatBounds,
|
||||
YMapLayerProps,
|
||||
YMapTileDataSourceProps,
|
||||
} from '@yandex/ymaps3-types'
|
||||
|
||||
const theme = 'black'
|
||||
const TILES_PATH = 'https://yastatic.net/s3/front-maps-static/maps-front-jsapi-3/examples/images/custom-map/tiles'
|
||||
|
||||
/* To calculate the coordinates of the lower left and upper right corners of a rectangular coordinate
|
||||
* area, we need to know the maximum zoom, width and height of the image in pixels at maximum zoom.
|
||||
*/
|
||||
const MAX_ZOOM = 4
|
||||
const MIN_ZOOM = 3
|
||||
const PIC_WIDTH = 2526
|
||||
const PIC_HEIGHT = 1642
|
||||
|
||||
const dataSourceProps: YMapTileDataSourceProps = {
|
||||
id: 'custom',
|
||||
raster: {
|
||||
type: 'ground',
|
||||
|
||||
/*
|
||||
fetchTile is called to get data for displaying a custom tile
|
||||
This method can be of several variants:
|
||||
1) x y z placeholders for tile coordinates
|
||||
2) method that returns final url
|
||||
3) method that fetches tile manually
|
||||
|
||||
In this example, we use option 1
|
||||
*/
|
||||
fetchTile: `${TILES_PATH}/{{z}}/tile-{{x}}-{{y}}.jpg`,
|
||||
},
|
||||
zoomRange: { min: MIN_ZOOM, max: MAX_ZOOM },
|
||||
clampMapZoom: true,
|
||||
}
|
||||
/*
|
||||
A text identifier is used to link the data source and the layer.
|
||||
Be careful, the identifier for the data source is set in the id field,
|
||||
and the source field is used when transferring to the layer
|
||||
*/
|
||||
const layerProps: YMapLayerProps = {
|
||||
id: 'customLayer',
|
||||
source: 'custom',
|
||||
type: 'ground',
|
||||
options: {
|
||||
raster: {
|
||||
awaitAllTilesOnFirstDisplay: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Calculate the size of all tiles at the maximum zoom.
|
||||
const worldSize = 2 ** MAX_ZOOM * 256
|
||||
|
||||
// Limiting the scrolling area of our map to the size of the entire image
|
||||
const RESTRICT_AREA: LngLatBounds = [
|
||||
[-PIC_WIDTH / 2, -PIC_HEIGHT / 2],
|
||||
[PIC_WIDTH / 2, PIC_HEIGHT / 2],
|
||||
]
|
||||
|
||||
const mapParameters: {
|
||||
mode: string
|
||||
worldOptions: { cycledY: boolean, cycledX: boolean }
|
||||
location: { center: [number, number], zoom: number }
|
||||
restrictMapArea: [[lon: number, lat: number, alt: number | undefined], [lon: number, lat: number, alt: number | undefined]]
|
||||
} = {
|
||||
location: { center: [0, 0], zoom: MAX_ZOOM },
|
||||
mode: 'raster',
|
||||
restrictMapArea: RESTRICT_AREA,
|
||||
// Do not copy the world along the axes
|
||||
// @ts-expect-error Яндекс забыли про cycledY в типах
|
||||
worldOptions: { cycledX: false, cycledY: false },
|
||||
}
|
||||
</script>
|
51
src/components/map.vue
Normal file
51
src/components/map.vue
Normal file
@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div class="map">
|
||||
<YandexMap
|
||||
v-model="map"
|
||||
:settings="{
|
||||
location: {
|
||||
center: merkuriyCoordinates,
|
||||
zoom: 16,
|
||||
},
|
||||
}"
|
||||
width="1270px"
|
||||
height="350px"
|
||||
>
|
||||
<YandexMapDefaultSchemeLayer />
|
||||
<YandexMapDefaultFeaturesLayer />
|
||||
<YandexMapMarker
|
||||
:settings="{ coordinates: merkuriyCoordinates }"
|
||||
>
|
||||
<a href="https://yandex.ru/maps/-/CDFyiEYK" target="_blank">
|
||||
<img
|
||||
class="pin"
|
||||
alt="#"
|
||||
src="../../public/shop.png"
|
||||
>
|
||||
</a>
|
||||
</YandexMapMarker>
|
||||
</YandexMap>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { YandexMap, YandexMapDefaultFeaturesLayer, YandexMapDefaultSchemeLayer, YandexMapMarker } from 'vue-yandex-maps'
|
||||
|
||||
const merkuriyCoordinates = [56.084516, 54.822215]
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.map {
|
||||
max-width: 1200px;
|
||||
}
|
||||
|
||||
.pin {
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
|
||||
cursor: pointer;
|
||||
max-width: unset;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
@ -1,11 +1,18 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
|
||||
import router from "./router/index.js"
|
||||
import router from './router/index.js'
|
||||
import './assets/index.scss'
|
||||
|
||||
// eslint-disable-next-line import/order
|
||||
import { createYmaps } from 'vue-yandex-maps'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app
|
||||
.use(router)
|
||||
.use(createYmaps({
|
||||
apikey: '13f4c06b-cb7e-4eeb-81f1-af52f12587b2',
|
||||
importModules: ['@yandex/ymaps3-controls@0.0.1'],
|
||||
}))
|
||||
.mount('#app')
|
||||
|
@ -1,228 +0,0 @@
|
||||
<template>
|
||||
<div class="createUser">
|
||||
<div class="container">
|
||||
<h1 class="createUser__title">Создание пользователя</h1>
|
||||
|
||||
<form @submit.prevent="submitForm" class="createUser__form">
|
||||
<h3>Персональные данные</h3>
|
||||
<div class="createUser__row">
|
||||
<AppInput
|
||||
placeholder='Введите фамилию'
|
||||
title="Фамилия"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
<AppInput
|
||||
placeholder='Введите имя'
|
||||
title="Имя"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
</div>
|
||||
<div class="createUser__row">
|
||||
<AppInput
|
||||
placeholder='Введите отчество'
|
||||
title="Отчество"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
<AppInput
|
||||
placeholder='Введите дату рождения'
|
||||
title="Дата рождения"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
</div>
|
||||
<div class="createUser__row">
|
||||
<AppSelect
|
||||
title="Укажите ваш пол"
|
||||
:items="['Мужской','Женский']"
|
||||
/>
|
||||
<AppSelect
|
||||
title="Группа клиентов"
|
||||
:items="['Vip','Проблемные','ОМС']"
|
||||
/>
|
||||
</div>
|
||||
<div class="createUser__row">
|
||||
<AppInput
|
||||
placeholder='Введите номер телефона'
|
||||
title="Номер телефона"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
<AppSelect
|
||||
title="Лечющий врач"
|
||||
:items="['Иванов', 'Захаров', 'Чернышева']"
|
||||
/>
|
||||
</div>
|
||||
<div class="createUser__row">
|
||||
<AppCheckbox
|
||||
class="createUser__checkbox"
|
||||
text="Не отправлять СМС"
|
||||
id="checkboxIsActive"
|
||||
v-model:checked="checkboxIsActive"/>
|
||||
</div>
|
||||
|
||||
<h3>Адресс</h3>
|
||||
<div class="createUser__row">
|
||||
<AppInput
|
||||
placeholder='Введите индекс'
|
||||
title="Индекс"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
<AppInput
|
||||
placeholder='Введите вашу страну'
|
||||
title="Страна"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
</div>
|
||||
<div class="createUser__row">
|
||||
<AppInput
|
||||
placeholder='Введите вагу область'
|
||||
title="Область"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
<AppInput
|
||||
placeholder='Введите ваш город'
|
||||
title="Город"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
</div>
|
||||
<div class="createUser__row">
|
||||
<AppInput
|
||||
placeholder='Введите вашу улицу'
|
||||
title="Улица"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
<AppInput
|
||||
placeholder='Введите ваш номер дома'
|
||||
title="Дом"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<h3>Паспортные данные</h3>
|
||||
<div class="createUser__row">
|
||||
<AppSelect
|
||||
title='Выберите документ'
|
||||
:items="['Паспорт','Свидетельство о рождении','Водительское удостоверение']"
|
||||
/>
|
||||
<AppInput
|
||||
placeholder='Введите серию'
|
||||
title="Серия"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
</div>
|
||||
<div class="createUser__row">
|
||||
<AppInput
|
||||
placeholder='Введите номер'
|
||||
title="Номер"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
<AppInput
|
||||
placeholder='Дата'
|
||||
title="Дата выдвчи"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
</div>
|
||||
<div class="createUser__row">
|
||||
<AppInput
|
||||
width="100%"
|
||||
placeholder='Введите название оргонизации'
|
||||
title="Кем выдан"
|
||||
v-model:value="v$.nameField.$model"
|
||||
:error="v$.nameField.$errors"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<AppButton medium type="Submit">Confirm</AppButton>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import AppButton from "../components/app-button.vue";
|
||||
import AppInput from "../components/app-input.vue";
|
||||
|
||||
import {computed, ref} from "vue";
|
||||
import {email, helpers, minLength} from "@vuelidate/validators";
|
||||
import useVuelidate from "@vuelidate/core";
|
||||
import AppCheckbox from "../components/app-checkbox.vue";
|
||||
import AppSelect from "../components/app-select.vue";
|
||||
|
||||
const checkboxIsActive = ref(false)
|
||||
|
||||
const nameField = ref('')
|
||||
const emailField = ref('')
|
||||
|
||||
const rules = computed(() => ({
|
||||
nameField: {
|
||||
required: true,
|
||||
minLength: helpers.withMessage(`Минимальная длина: 6 символа`, minLength(6))
|
||||
},
|
||||
emailField: {
|
||||
required: true,
|
||||
email: helpers.withMessage('Вы ввели неверный email', email)
|
||||
},
|
||||
}))
|
||||
|
||||
const v$ = useVuelidate(rules, {nameField, emailField})
|
||||
|
||||
function submitForm() {
|
||||
alert('pizda')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.createUser {
|
||||
height: 100%;
|
||||
|
||||
&__title {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
&__form {
|
||||
//display: flex;
|
||||
flex-direction: column;
|
||||
gap: 30px;
|
||||
height: 100%;
|
||||
|
||||
@media (max-width: 700px) {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
&__row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
@media (max-width: 700px) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
&__checkbox {
|
||||
margin-top: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.inputblock {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 30px;
|
||||
}
|
||||
</style>
|
31
src/pages/map.vue
Normal file
31
src/pages/map.vue
Normal file
@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<div class="map-page">
|
||||
<div class="container">
|
||||
<h1>Карта</h1>
|
||||
<Map />
|
||||
<h1 class="custom">
|
||||
Карта торгового центра
|
||||
</h1>
|
||||
<CustomMap />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import CustomMap from '../components/custom-map.vue'
|
||||
import Map from '../components/map.vue'
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.map-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.custom {
|
||||
margin-top: 200px;
|
||||
margin-block: auto;
|
||||
}
|
||||
</style>
|
@ -1,10 +1,10 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import Test from "../pages/createUser.vue";
|
||||
import Map from '../pages/map.vue'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
component: Test,
|
||||
component: Map,
|
||||
},
|
||||
]
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user