Feat new site version

This commit is contained in:
Jean Andreani
2023-10-10 16:15:03 +00:00
parent 3b7c61dba5
commit 3f88a70544
71 changed files with 3131 additions and 2407 deletions

View File

@@ -5,6 +5,10 @@
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
<excludeFolder url="file://$MODULE_DIR$/.idea/codeStyles" />
<excludeFolder url="file://$MODULE_DIR$/.idea/jsLinters" />
<excludeFolder url="file://$MODULE_DIR$/cypress/videos" />
<excludeFolder url="file://$MODULE_DIR$/src/node_modules" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />

View File

@@ -2,5 +2,21 @@
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true">
<option name="myValues">
<value>
<list size="7">
<item index="0" class="java.lang.String" itemvalue="nobr" />
<item index="1" class="java.lang.String" itemvalue="noembed" />
<item index="2" class="java.lang.String" itemvalue="comment" />
<item index="3" class="java.lang.String" itemvalue="noscript" />
<item index="4" class="java.lang.String" itemvalue="embed" />
<item index="5" class="java.lang.String" itemvalue="script" />
<item index="6" class="java.lang.String" itemvalue="div" />
</list>
</value>
</option>
<option name="myCustomValuesEnabled" value="true" />
</inspection_tool>
</profile>
</component>

1
bootstrap.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
declare module 'bootstrap'

View File

@@ -1,11 +0,0 @@
describe('In the home page', () => {
it('click on the link in the header to go to the upload page', () => {
cy.visit('/')
cy.fixture('home').then((homeData) => {
cy.contains(homeData.textLinkUpload).click()
cy.url().should('include', '/partager-des-photos')
})
})
})
export {}

View File

@@ -1,5 +0,0 @@
{
"addressToSearch": "97 boulevard Voltaire 75011 paris",
"textAddressToSelect": "Boulevard Voltaire, Quartier de la Folie-Méricourt, Paris 11e Arrondissement, Paris, Île-de-France, France métropolitaine, 75011, France",
"textLinkUpload": "À propos"
}

View File

@@ -25,7 +25,7 @@
"axios": "^1.2.3",
"bootstrap": "^5.2.3",
"bootstrap-icons": "^1.10.3",
"geovisio": "2.1.4",
"geovisio": "2.2.0",
"moment": "^2.29.4",
"pinia": "^2.1.4",
"vue": "^3.2.45",

View File

@@ -1,13 +1,18 @@
<script setup lang="ts">
import { ref } from 'vue'
import Header from '@/components/Header.vue'
import Footer from '@/components/Footer.vue'
import { RouterView } from 'vue-router'
import { useMeta } from 'vue-meta'
import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router'
import { title } from '@/utils/index'
import authConfig from './composables/auth'
const { authConf } = authConfig()
const { t } = useI18n()
const route = useRoute()
let focusMap = ref<string>('focus-map')
useMeta({
title: title(t('general.title')),
@@ -20,6 +25,10 @@ useMeta({
description: title(t('general.meta.description'))
}
})
function setFocusMap(value: string) {
focusMap.value = value
}
</script>
<template>
@@ -41,7 +50,13 @@ useMeta({
: ''
"
/>
<RouterView />
<Footer />
<RouterView @trigger="setFocusMap" />
<Footer
v-if="
route.name !== 'sequence' &&
route.name !== 'my-sequences' &&
focusMap === 'focus-map'
"
/>
</template>
<style scoped></style>

View File

@@ -1,39 +1,59 @@
@mixin text($size) {
@if $size == h1 {
font-weight: normal;
font-size: toRem(4);
font-weight: 590;
line-height: toRem(2.6);
font-size: toRem(2.2);
@media (max-width: toRem(50)) {
font-size: toRem(2.6);
font-size: toRem(2);
}
}
@if $size == h2 {
font-weight: normal;
font-weight: 590;
font-size: toRem(2);
line-height: toRem(2.4);
@media (max-width: toRem(50)) {
font-size: toRem(1.8);
font-size: toRem(1.6);
}
}
@if $size == h3 {
font-weight: 590;
font-size: toRem(1.8);
line-height: toRem(2.1);
@media (max-width: toRem(50)) {
font-size: toRem(1.6);
}
}
@if $size == h4 {
font-weight: normal;
font-size: toRem(1.6);
}
@if $size == xxl-regular {
font-size: toRem(3.2);
font-weight: normal;
}
@if $size == m-regular {
font-size: toRem(1.6);
font-weight: normal;
}
@if $size == s-regular {
font-size: toRem(1.4);
font-weight: normal;
}
@if $size == xss-regular {
font-size: toRem(0.9);
font-weight: normal;
}
@if $size == m-r-regular {
font-size: toRem(1.6);
font-weight: normal;
@media (max-width: toRem(50)) {
font-size: toRem(1.2);
font-size: toRem(1.4);
}
}
@if $size == s-regular {
font-size: toRem(1.4);
font-weight: normal;
}
@if $size == xs-r-regular {
font-size: toRem(1.2);
font-weight: normal;
@@ -41,8 +61,11 @@
font-size: toRem(1);
}
}
@if $size == xss-regular {
font-size: toRem(0.9);
@if $size == s-r-regular {
font-size: toRem(1.4);
font-weight: normal;
@media (max-width: toRem(50)) {
font-size: toRem(1.2);
}
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -0,0 +1,32 @@
<svg width="80" height="71" viewBox="0 0 80 71" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="47.5" cy="38" r="32.5" fill="#F2F5FF"/>
<path d="M51.2768 56.873H18.3615C17.7586 56.873 17.2734 56.3879 17.2734 55.7849V1.58811C17.2734 0.985114 17.7586 0.5 18.3615 0.5H51.2768C51.8798 0.5 52.3649 0.985114 52.3649 1.58811V55.7849C52.3649 56.3879 51.8752 56.873 51.2768 56.873ZM19.4497 54.6968H50.1887V2.67621H19.4497V54.6968Z" fill="#0A1F69"/>
<path d="M27.8776 12.1926H22.7273C22.1243 12.1926 21.6392 11.7075 21.6392 11.1045V5.94956C21.6392 5.34656 22.1243 4.86145 22.7273 4.86145H27.8822C28.4852 4.86145 28.9703 5.34656 28.9703 5.94956V11.0999C28.9657 11.7029 28.4806 12.1926 27.8776 12.1926ZM23.8154 10.0164H26.7941V7.0422H23.8154V10.0164Z" fill="#0A1F69"/>
<path d="M37.394 12.1926H32.2436C31.6406 12.1926 31.1555 11.7075 31.1555 11.1045V5.94956C31.1555 5.34656 31.6406 4.86145 32.2436 4.86145H37.394C37.997 4.86145 38.4821 5.34656 38.4821 5.94956V11.0999C38.4821 11.7029 37.997 12.1926 37.394 12.1926ZM33.3317 10.0164H36.3059V7.0422H33.3317V10.0164Z" fill="#0A1F69"/>
<path d="M37.394 12.1926H32.2436C31.6406 12.1926 31.1555 11.7075 31.1555 11.1045V5.94956C31.1555 5.34656 31.6406 4.86145 32.2436 4.86145H37.394C37.997 4.86145 38.4821 5.34656 38.4821 5.94956V11.0999C38.4821 11.7029 37.997 12.1926 37.394 12.1926ZM33.3317 10.0164H36.3059V7.0422H33.3317V10.0164Z" fill="#0A1F69"/>
<path d="M46.9106 12.1926H41.7602C41.1572 12.1926 40.6721 11.7075 40.6721 11.1045V5.94956C40.6721 5.34656 41.1572 4.86145 41.7602 4.86145H46.9151C47.5181 4.86145 48.0032 5.34656 48.0032 5.94956V11.0999C47.9987 11.7029 47.5136 12.1926 46.9106 12.1926ZM42.8483 10.0164H45.827V7.0422H42.8483V10.0164Z" fill="#0A1F69"/>
<path d="M27.8776 21.709H22.7273C22.1243 21.709 21.6392 21.2239 21.6392 20.6209V15.466C21.6392 14.863 22.1243 14.3779 22.7273 14.3779H27.8822C28.4852 14.3779 28.9703 14.863 28.9703 15.466V20.6209C28.9657 21.2194 28.4806 21.709 27.8776 21.709ZM23.8154 19.5328H26.7941V16.5541H23.8154V19.5328Z" fill="#0A1F69"/>
<path d="M37.394 21.709H32.2436C31.6406 21.709 31.1555 21.2239 31.1555 20.6209V15.466C31.1555 14.863 31.6406 14.3779 32.2436 14.3779H37.3985C38.0015 14.3779 38.4866 14.863 38.4866 15.466V20.6209C38.4821 21.2194 37.997 21.709 37.394 21.709ZM33.3317 19.5328H36.3104V16.5541H33.3317V19.5328Z" fill="#0A1F69"/>
<path d="M37.394 21.709H32.2436C31.6406 21.709 31.1555 21.2239 31.1555 20.6209V15.466C31.1555 14.863 31.6406 14.3779 32.2436 14.3779H37.3985C38.0015 14.3779 38.4866 14.863 38.4866 15.466V20.6209C38.4821 21.2194 37.997 21.709 37.394 21.709ZM33.3317 19.5328H36.3104V16.5541H33.3317V19.5328Z" fill="#0A1F69"/>
<path d="M46.9106 21.709H41.7602C41.1572 21.709 40.6721 21.2239 40.6721 20.6209V15.466C40.6721 14.863 41.1572 14.3779 41.7602 14.3779H46.9151C47.5181 14.3779 48.0032 14.863 48.0032 15.466V20.6209C47.9987 21.2194 47.5136 21.709 46.9106 21.709ZM42.8483 19.5328H45.827V16.5541H42.8483V19.5328Z" fill="#0A1F69"/>
<path d="M27.8776 31.2254H22.7273C22.1243 31.2254 21.6392 30.7403 21.6392 30.1373V24.9824C21.6392 24.3794 22.1243 23.8943 22.7273 23.8943H27.8822C28.4852 23.8943 28.9703 24.3794 28.9703 24.9824V30.1373C28.9657 30.7358 28.4806 31.2254 27.8776 31.2254ZM23.8154 29.0492H26.7941V26.0705H23.8154V29.0492Z" fill="#0A1F69"/>
<path d="M37.394 31.2254H32.2436C31.6406 31.2254 31.1555 30.7403 31.1555 30.1373V24.9824C31.1555 24.3794 31.6406 23.8943 32.2436 23.8943H37.3985C38.0015 23.8943 38.4866 24.3794 38.4866 24.9824V30.1373C38.4821 30.7358 37.997 31.2254 37.394 31.2254ZM33.3317 29.0492H36.3059V26.0705H33.3272L33.3317 29.0492Z" fill="#0A1F69"/>
<path d="M37.394 31.2254H32.2436C31.6406 31.2254 31.1555 30.7403 31.1555 30.1373V24.9824C31.1555 24.3794 31.6406 23.8943 32.2436 23.8943H37.3985C38.0015 23.8943 38.4866 24.3794 38.4866 24.9824V30.1373C38.4821 30.7358 37.997 31.2254 37.394 31.2254ZM33.3317 29.0492H36.3059V26.0705H33.3272L33.3317 29.0492Z" fill="#0A1F69"/>
<path d="M46.9106 31.2254H41.7602C41.1572 31.2254 40.6721 30.7403 40.6721 30.1373V24.9824C40.6721 24.3794 41.1572 23.8943 41.7602 23.8943H46.9151C47.5181 23.8943 48.0032 24.3794 48.0032 24.9824V30.1373C47.9987 30.7358 47.5136 31.2254 46.9106 31.2254ZM42.8483 29.0492H45.827V26.0705H42.8483V29.0492Z" fill="#0A1F69"/>
<path d="M65.1547 56.8729H51.2768C50.6738 56.8729 50.1887 56.3878 50.1887 55.7848V13.3578C50.1887 12.7548 50.6738 12.2697 51.2768 12.2697H65.1547C65.7577 12.2697 66.2428 12.7548 66.2428 13.3578V55.7848C66.2428 56.3878 65.7577 56.8729 65.1547 56.8729ZM52.3649 54.6967H64.0666V14.4459H52.3649V54.6967Z" fill="#0A1F69"/>
<path d="M60.7932 23.9622H55.6428C55.0398 23.9622 54.5547 23.4771 54.5547 22.8741V17.7237C54.5547 17.1207 55.0398 16.6356 55.6428 16.6356H60.7932C61.3962 16.6356 61.8813 17.1207 61.8813 17.7237V22.8786C61.8813 23.4771 61.3916 23.9622 60.7932 23.9622ZM56.7264 21.786H59.7005V18.8073H56.7264V21.786Z" fill="#0A1F69"/>
<path d="M60.7929 33.4786H55.6425C55.0396 33.4786 54.5544 32.9934 54.5544 32.3905V27.2401C54.5544 26.6371 55.0396 26.152 55.6425 26.152H60.7929C61.3959 26.152 61.881 26.6371 61.881 27.2401V32.395C61.881 32.9934 61.3914 33.4786 60.7929 33.4786ZM56.7261 31.3023H59.7003V28.3237H56.7261V31.3023Z" fill="#0A1F69"/>
<path d="M60.7929 42.9949H55.6425C55.0396 42.9949 54.5544 42.5098 54.5544 41.9068V36.7519C54.5544 36.1489 55.0396 35.6638 55.6425 35.6638H60.7929C61.3959 35.6638 61.881 36.1489 61.881 36.7519V41.9068C61.881 42.5098 61.3914 42.9949 60.7929 42.9949ZM56.7261 40.8187H59.7003V37.84H56.7261V40.8187Z" fill="#0A1F69"/>
<path d="M60.7929 52.5114H55.6425C55.0396 52.5114 54.5544 52.0263 54.5544 51.4233V46.2684C54.5544 45.6654 55.0396 45.1803 55.6425 45.1803H60.7929C61.3959 45.1803 61.881 45.6654 61.881 46.2684V51.4233C61.881 52.0218 61.3914 52.5114 60.7929 52.5114ZM56.7261 50.3352H59.7003V47.3565H56.7261V50.3352Z" fill="#0A1F69"/>
<path d="M18.3615 56.873H4.48361C3.88062 56.873 3.39551 56.3879 3.39551 55.7849V21.5141C3.39551 21.1287 3.59953 20.7706 3.93049 20.5756L17.8084 12.4194C18.1439 12.2199 18.561 12.2199 18.901 12.4148C19.2411 12.6098 19.4496 12.9679 19.4496 13.3578V55.7849C19.4496 56.3879 18.9645 56.873 18.3615 56.873ZM5.57172 54.6968H17.2734V15.2575L5.57172 22.1352V54.6968Z" fill="#0A1F69"/>
<path d="M13.9998 52.5115H8.84494C8.24195 52.5115 7.75684 52.0264 7.75684 51.4234V46.273C7.75684 45.6701 8.24195 45.1849 8.84494 45.1849H13.9953C14.5983 45.1849 15.0834 45.6701 15.0834 46.273V51.4234C15.088 52.0219 14.5983 52.5115 13.9998 52.5115ZM9.93305 50.3353H12.9117V47.3611H9.93758L9.93305 50.3353Z" fill="#0A1F69"/>
<path d="M13.9998 33.4787H8.84494C8.24195 33.4787 7.75684 32.9936 7.75684 32.3906V27.2402C7.75684 26.6372 8.24195 26.1521 8.84494 26.1521H13.9953C14.5983 26.1521 15.0834 26.6372 15.0834 27.2402V32.3951C15.088 32.9936 14.5983 33.4787 13.9998 33.4787ZM9.93305 31.3025H12.9072V28.3238H9.93305V31.3025Z" fill="#0A1F69"/>
<path d="M13.9998 42.9951H8.84494C8.24195 42.9951 7.75684 42.5099 7.75684 41.9069V36.752C7.75684 36.1491 8.24195 35.6639 8.84494 35.6639H13.9953C14.5983 35.6639 15.0834 36.1491 15.0834 36.752V41.9069C15.088 42.5054 14.5983 42.9951 13.9998 42.9951ZM9.93305 40.8188H12.9072V37.8402H9.93305V40.8188Z" fill="#0A1F69"/>
<path d="M27.8779 40.7418H22.7275C22.1245 40.7418 21.6394 40.2566 21.6394 39.6537V34.4988C21.6394 33.8958 22.1245 33.4106 22.7275 33.4106H27.8824C28.4854 33.4106 28.9705 33.8958 28.9705 34.4988V39.6537C28.966 40.2521 28.4809 40.7418 27.8779 40.7418ZM23.8156 38.5655H26.7943V35.5869H23.8156V38.5655Z" fill="#0A1F69"/>
<path d="M37.3942 40.7418H32.2439C31.6409 40.7418 31.1558 40.2566 31.1558 39.6537V34.4988C31.1558 33.8958 31.6409 33.4106 32.2439 33.4106H37.3988C38.0018 33.4106 38.4869 33.8958 38.4869 34.4988V39.6491C38.4823 40.2521 37.9972 40.7418 37.3942 40.7418ZM33.332 38.5655H36.3061V35.5914H33.3274L33.332 38.5655Z" fill="#0A1F69"/>
<path d="M37.3942 40.7418H32.2439C31.6409 40.7418 31.1558 40.2566 31.1558 39.6537V34.4988C31.1558 33.8958 31.6409 33.4106 32.2439 33.4106H37.3988C38.0018 33.4106 38.4869 33.8958 38.4869 34.4988V39.6491C38.4823 40.2521 37.9972 40.7418 37.3942 40.7418ZM33.332 38.5655H36.3061V35.5914H33.3274L33.332 38.5655Z" fill="#0A1F69"/>
<path d="M46.9108 40.7418H41.7605C41.1575 40.7418 40.6724 40.2566 40.6724 39.6537V34.4988C40.6724 33.8958 41.1575 33.4106 41.7605 33.4106H46.9108C47.5138 33.4106 47.9989 33.8958 47.9989 34.4988V39.6537C47.9989 40.2521 47.5138 40.7418 46.9108 40.7418ZM42.8486 38.5655H45.8227V35.5869H42.8486V38.5655Z" fill="#0A1F69"/>
<path d="M41.7603 56.8729H27.8779C27.2749 56.8729 26.7898 56.3878 26.7898 55.7848V44.201C26.7898 43.598 27.2749 43.1129 27.8779 43.1129H41.7558C42.3588 43.1129 42.8439 43.598 42.8439 44.201V55.7848C42.8484 56.3878 42.3588 56.8729 41.7603 56.8729ZM28.966 54.6967H40.6677V45.2891H28.966V54.6967Z" fill="#0A1F69"/>
<path d="M34.8191 56.8729C34.2161 56.8729 33.731 56.3878 33.731 55.7848V44.201C33.731 43.598 34.2161 43.1129 34.8191 43.1129C35.4221 43.1129 35.9072 43.598 35.9072 44.201V55.7848C35.9072 56.3878 35.4221 56.8729 34.8191 56.8729Z" fill="#0A1F69"/>
<path d="M68.5507 60.5H1.08811C0.485114 60.5 0 60.0149 0 59.4119V55.7849C0 55.1819 0.485114 54.6968 1.08811 54.6968H68.5507C69.1537 54.6968 69.6388 55.1819 69.6388 55.7849V59.4119C69.6388 60.0149 69.1537 60.5 68.5507 60.5ZM2.17621 58.3238H67.4626V56.873H2.17621V58.3238Z" fill="#0A1F69"/>
</svg>

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,16 @@
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200">
<title>Nouveau projet</title>
<defs>
<image width="200" height="200" id="img1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAQMAAACXljzdAAAAAXNSR0IB2cksfwAAAANQTFRF////p8QbyAAAABxJREFUeJztwYEAAAAAw6D5U1/hAFUBAAAAAHwGFFAAAdqgEPkAAAAASUVORK5CYII="/>
</defs>
<style>
.s0 { fill: #e24329 }
.s1 { fill: #fc6d26 }
.s2 { fill: #fca326 }
</style>
<use id="Background" href="#img1" x="0" y="0"/>
<path id="Layer copy 2" class="s0" d="m192.8 80.7l-0.2-0.7-26.2-68.2q-0.2-0.5-0.5-0.9-0.2-0.5-0.6-0.9-0.3-0.4-0.7-0.8-0.4-0.3-0.9-0.6-0.9-0.6-1.9-0.9-1.1-0.2-2.1-0.2-1.1 0.1-2.1 0.5-1 0.3-1.9 1-0.4 0.3-0.7 0.7-0.4 0.4-0.7 0.9-0.3 0.4-0.5 0.9-0.2 0.5-0.4 1l-17.6 54h-71.5l-17.7-54q-0.1-0.5-0.3-1-0.2-0.5-0.5-0.9-0.3-0.5-0.7-0.9-0.4-0.4-0.8-0.7-0.8-0.7-1.8-1-1-0.4-2.1-0.5-1.1 0-2.1 0.2-1.1 0.3-2 0.9-0.4 0.3-0.8 0.6-0.4 0.4-0.8 0.8-0.3 0.4-0.6 0.9-0.3 0.4-0.5 0.9l-26.2 68.2-0.2 0.7c-1.9 4.9-3 10-3.2 15.3-0.2 5.2 0.4 10.4 1.9 15.4 1.4 5.1 3.6 9.8 6.6 14.1 3 4.3 6.6 8.1 10.8 11.3l0.1 0.1 0.2 0.1 39.8 29.8 19.7 15 12 9q1.1 0.8 2.3 1.2 1.3 0.5 2.6 0.5 1.3 0 2.6-0.5 1.2-0.4 2.3-1.2l12-9 19.7-15 40-30h0.1c4.2-3.2 7.8-7 10.8-11.3 3-4.3 5.2-9 6.6-14.1 1.5-5 2.1-10.2 1.9-15.4-0.2-5.2-1.3-10.4-3.2-15.3z"/>
<path id="Layer" class="s1" d="m192.8 80.7l-0.2-0.7q-4.8 1-9.4 2.5-4.7 1.5-9.1 3.5-4.4 2-8.6 4.5-4.2 2.4-8.1 5.3l-57.4 43.4c19.5 14.8 36.6 27.7 36.6 27.7l40-30 0.1-0.1c4.2-3.1 7.8-6.9 10.8-11.3 3-4.3 5.2-9 6.6-14 1.5-5.1 2.1-10.3 1.9-15.5-0.2-5.2-1.3-10.4-3.2-15.3z"/>
<path id="Layer" class="s2" d="m63.4 166.9l19.7 14.9 12 9.1q1.1 0.8 2.3 1.2 1.3 0.4 2.6 0.4 1.3 0 2.6-0.4 1.2-0.4 2.3-1.2l12-9.1 19.7-14.9c0 0-17-12.9-36.6-27.7-19.6 14.8-36.6 27.7-36.6 27.7z"/>
<path id="Layer" class="s1" d="m42.6 95.8q-3.9-2.9-8.1-5.4-4.2-2.4-8.6-4.4-4.4-2-9.1-3.5-4.6-1.5-9.4-2.5l-0.2 0.7c-1.9 4.9-3 10-3.2 15.3-0.2 5.2 0.4 10.4 1.9 15.4 1.4 5.1 3.6 9.8 6.6 14.1 3 4.3 6.6 8.1 10.8 11.3l0.1 0.1 0.2 0.1 39.8 29.8c0 0 17-12.8 36.6-27.6z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@@ -0,0 +1,3 @@
<svg width="10" height="7" viewBox="0 0 10 7" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 6.343L0 0.157104L10 0.157105L5 6.343Z" fill="#0A1F69"/>
</svg>

After

Width:  |  Height:  |  Size: 169 B

View File

@@ -0,0 +1,3 @@
<svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 0.5C4.47719 0.5 0 4.97719 0 10.5C0 16.0231 4.47719 20.5 10 20.5C15.5231 20.5 20 16.0231 20 10.5C20 4.97719 15.5231 0.5 10 0.5ZM10 19.2697C5.17531 19.2697 1.25 15.3247 1.25 10.5C1.25 5.67527 5.17531 1.74996 10 1.74996C14.8247 1.74996 18.75 5.67529 18.75 10.5C18.75 15.3246 14.8247 19.2697 10 19.2697ZM13.9909 6.84094L8.12373 12.745L5.48154 10.1028C5.23748 9.85875 4.84186 9.85875 4.59748 10.1028C4.35342 10.3469 4.35342 10.7425 4.59748 10.9866L7.69092 14.0803C7.93498 14.3241 8.33061 14.3241 8.57498 14.0803C8.60311 14.0522 8.62719 14.0215 8.64906 13.9897L14.8753 7.72498C15.1191 7.48092 15.1191 7.08529 14.8753 6.84094C14.6309 6.59688 14.2353 6.59688 13.9909 6.84094Z" fill="#68C149"/>
</svg>

After

Width:  |  Height:  |  Size: 802 B

View File

@@ -0,0 +1,3 @@
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11 8.64286C11.2084 8.64286 11.4082 8.72564 11.5556 8.87299C11.7029 9.02034 11.7857 9.22019 11.7857 9.42857V16.5C11.7857 16.7084 11.7029 16.9082 11.5556 17.0556C11.4082 17.2029 11.2084 17.2857 11 17.2857C10.7916 17.2857 10.5918 17.2029 10.4444 17.0556C10.2971 16.9082 10.2143 16.7084 10.2143 16.5V9.42857C10.2143 9.22019 10.2971 9.02034 10.4444 8.87299C10.5918 8.72564 10.7916 8.64286 11 8.64286ZM11 7.07143C11.3126 7.07143 11.6123 6.94726 11.8334 6.72623C12.0544 6.50521 12.1786 6.20543 12.1786 5.89286C12.1786 5.58028 12.0544 5.28051 11.8334 5.05948C11.6123 4.83846 11.3126 4.71429 11 4.71429C10.6874 4.71429 10.3876 4.83846 10.1666 5.05948C9.9456 5.28051 9.82143 5.58028 9.82143 5.89286C9.82143 6.20543 9.9456 6.50521 10.1666 6.72623C10.3876 6.94726 10.6874 7.07143 11 7.07143ZM0 11C0 4.92486 4.92486 0 11 0C17.0751 0 22 4.92486 22 11C22 17.0751 17.0751 22 11 22C4.92486 22 0 17.0751 0 11ZM11 1.57143C5.79307 1.57143 1.57143 5.79307 1.57143 11C1.57143 16.2069 5.79307 20.4286 11 20.4286C16.2069 20.4286 20.4286 16.2069 20.4286 11C20.4286 5.79307 16.2069 1.57143 11 1.57143Z" fill="#0A1F69"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20 9.99C20 4.475 15.52 0 10 0C4.48 0 0 4.475 0 9.99C0 13.0275 1.38 15.765 3.54 17.6025C3.56 17.6225 3.58 17.6225 3.58 17.6425C3.76 17.7825 3.94 17.9225 4.14 18.0625C4.24 18.1225 4.32 18.2013 4.42 18.2812C6.07258 19.4017 8.02339 20.0004 10.02 20C12.0166 20.0004 13.9674 19.4017 15.62 18.2812C15.72 18.2213 15.8 18.1425 15.9 18.0812C16.08 17.9425 16.28 17.8025 16.46 17.6625C16.48 17.6425 16.5 17.6425 16.5 17.6225C18.62 15.7637 20 13.0275 20 9.99ZM10 18.7412C8.12 18.7412 6.4 18.1413 4.98 17.1425C5 16.9825 5.04 16.8237 5.08 16.6637C5.19917 16.2301 5.37396 15.8138 5.6 15.425C5.82 15.045 6.08 14.705 6.4 14.405C6.7 14.105 7.06 13.8263 7.42 13.6063C7.8 13.3863 8.2 13.2262 8.64 13.1062C9.08342 12.9867 9.54075 12.9266 10 12.9275C11.3633 12.9178 12.6765 13.4408 13.66 14.385C14.12 14.845 14.48 15.385 14.74 16.0037C14.88 16.3638 14.98 16.7437 15.04 17.1425C13.564 18.1802 11.8043 18.7384 10 18.7412ZM6.94 9.49125C6.76378 9.08778 6.67516 8.6515 6.68 8.21125C6.68 7.7725 6.76 7.3325 6.94 6.9325C7.12 6.5325 7.36 6.17375 7.66 5.87375C7.96 5.57375 8.32 5.335 8.72 5.155C9.12 4.975 9.56 4.895 10 4.895C10.46 4.895 10.88 4.975 11.28 5.155C11.68 5.335 12.04 5.575 12.34 5.87375C12.64 6.17375 12.88 6.53375 13.06 6.9325C13.24 7.3325 13.32 7.7725 13.32 8.21125C13.32 8.67125 13.24 9.09125 13.06 9.49C12.8863 9.88408 12.6423 10.2433 12.34 10.55C12.0332 10.8519 11.674 11.0954 11.28 11.2688C10.4535 11.6084 9.52647 11.6084 8.7 11.2688C8.30602 11.0954 7.94684 10.8519 7.64 10.55C7.33727 10.2477 7.09912 9.88836 6.94 9.49125ZM16.22 16.1238C16.22 16.0837 16.2 16.0638 16.2 16.0238C16.0033 15.398 15.7134 14.8055 15.34 14.2663C14.9663 13.723 14.507 13.2438 13.98 12.8475C13.5775 12.5447 13.1413 12.2897 12.68 12.0875C12.8899 11.9491 13.0843 11.7886 13.26 11.6087C13.5582 11.3144 13.82 10.9854 14.04 10.6287C14.4829 9.90101 14.7117 9.06311 14.7 8.21125C14.7062 7.58064 14.5837 6.9554 14.34 6.37375C14.0994 5.8133 13.7531 5.30445 13.32 4.875C12.8876 4.45004 12.3786 4.11074 11.82 3.875C11.2374 3.63174 10.6113 3.50968 9.98 3.51625C9.34859 3.51007 8.72253 3.63256 8.14 3.87625C7.57657 4.11148 7.06639 4.45798 6.64 4.895C6.21505 5.32698 5.87574 5.83552 5.64 6.39375C5.39631 6.9754 5.27381 7.60064 5.28 8.23125C5.28 8.67125 5.34 9.09125 5.46 9.49C5.58 9.91 5.74 10.29 5.96 10.6488C6.16 11.0087 6.44 11.3288 6.74 11.6288C6.92 11.8088 7.12 11.9675 7.34 12.1075C6.87729 12.3151 6.4409 12.5769 6.04 12.8875C5.52 13.2875 5.06 13.7662 4.68 14.2863C4.30282 14.8233 4.0126 15.4164 3.82 16.0438C3.8 16.0837 3.8 16.1238 3.8 16.1437C2.22 14.545 1.24 12.3875 1.24 9.99C1.24 5.175 5.18 1.23875 10 1.23875C14.82 1.23875 18.76 5.175 18.76 9.99C18.7574 12.2899 17.8441 14.4953 16.22 16.1238Z" fill="#0A1F69"/>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,4 @@
<svg width="19" height="20" viewBox="0 0 19 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.64616 0.247477L7.13749 2.38744C6.86416 2.77517 7.14249 3.31107 7.61639 3.31107H8.53913V13.5861C8.53913 13.9097 8.80147 14.1721 9.1251 14.1721C9.44874 14.1721 9.71104 13.9097 9.71104 13.5861V3.31115H10.6337C11.1108 3.31115 11.3839 2.7724 11.1126 2.38756L9.60397 0.247594C9.37374 -0.0792028 8.88163 -0.085804 8.64616 0.247477Z" fill="#0A1F69"/>
<path d="M12.8875 3.18472C12.7256 3.46476 12.8212 3.82327 13.1013 3.98534C15.4809 5.36175 17.0783 7.93468 17.0783 10.8749C17.0783 15.2603 13.5105 18.8281 9.12512 18.8281C4.73973 18.8281 1.17191 15.2603 1.17191 10.8749C1.17191 7.93273 2.77086 5.36097 5.14883 3.98538C5.42899 3.82335 5.52457 3.46476 5.36266 3.18476C5.20063 2.90464 4.84215 2.80894 4.56203 2.97093C1.82539 4.55398 -1.47058e-07 7.51058 0 10.8749C2.20457e-07 15.9184 4.08121 20 9.12512 20C14.1686 20 18.2502 15.9188 18.2502 10.8749C18.2502 7.50913 16.4236 4.55327 13.6881 2.97089C13.408 2.8089 13.0496 2.9046 12.8875 3.18472Z" fill="#0A1F69"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,4 @@
<svg width="20" height="19" viewBox="0 0 20 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.2422 0.789062H4.29688C3.32762 0.789062 2.53906 1.57762 2.53906 2.54688V3.28906H1.75781C0.788555 3.28906 0 4.07762 0 5.04688V16.4531C0 17.4224 0.788555 18.2109 1.75781 18.2109H15.7031C16.6724 18.2109 17.4609 17.4224 17.4609 16.4531V15.7109H18.2422C19.2114 15.7109 20 14.9224 20 13.9531V2.54688C20 1.57762 19.2114 0.789062 18.2422 0.789062ZM4.29688 1.96094H18.2422C18.5653 1.96094 18.8281 2.22379 18.8281 2.54688V8.05477L15.3386 5.58426C15.1175 5.42781 14.818 5.44312 14.6141 5.62152L10 9.65891L7.88586 7.80902C7.67375 7.62348 7.35961 7.61512 7.13797 7.78926L3.71094 10.482V2.54688C3.71094 2.22379 3.97379 1.96094 4.29688 1.96094ZM16.2891 16.4531C16.2891 16.7762 16.0262 17.0391 15.7031 17.0391H1.75781C1.43473 17.0391 1.17188 16.7762 1.17188 16.4531V5.04688C1.17188 4.72379 1.43473 4.46094 1.75781 4.46094H2.53906V13.9531C2.53906 14.9224 3.32762 15.7109 4.29688 15.7109H16.2891V16.4531ZM18.2422 14.5391H4.29688C3.97379 14.5391 3.71094 14.2762 3.71094 13.9531V11.9723L7.47988 9.01098L9.61414 10.8785C9.83508 11.0718 10.1649 11.0718 10.3859 10.8785L15.0384 6.80758L18.8281 9.49059V13.9531C18.8281 14.2762 18.5653 14.5391 18.2422 14.5391Z" fill="#0A1F69"/>
<path d="M10 6.96094C11.0123 6.96094 11.8359 6.13734 11.8359 5.125C11.8359 4.11266 11.0123 3.28906 10 3.28906C8.98766 3.28906 8.16406 4.11266 8.16406 5.125C8.16406 6.13734 8.98766 6.96094 10 6.96094ZM10 4.46094C10.3662 4.46094 10.6641 4.75883 10.6641 5.125C10.6641 5.49117 10.3662 5.78906 10 5.78906C9.63383 5.78906 9.33594 5.49117 9.33594 5.125C9.33594 4.75883 9.63383 4.46094 10 4.46094Z" fill="#0A1F69"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,5 @@
<svg width="20" height="17" viewBox="0 0 20 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.585938 3.4375H11.9953C12.2591 4.51676 13.2339 5.32027 14.3932 5.32027C15.5526 5.32027 16.5274 4.51676 16.7912 3.4375H19.4141C19.7377 3.4375 20 3.17516 20 2.85156C20 2.52797 19.7377 2.26563 19.4141 2.26563H16.7912C16.5274 1.18637 15.5526 0.382812 14.3932 0.382812C13.2339 0.382812 12.2591 1.18637 11.9953 2.26563H0.585938C0.262344 2.26563 0 2.52797 0 2.85156C0 3.17516 0.262344 3.4375 0.585938 3.4375ZM14.3932 1.55469C15.1084 1.55469 15.6901 2.13648 15.6901 2.85156C15.6901 3.56664 15.1083 4.1484 14.3932 4.1484C13.6782 4.1484 13.0964 3.5666 13.0964 2.85156C13.0964 2.13648 13.6781 1.55469 14.3932 1.55469Z" fill="#0A1F69"/>
<path d="M19.4141 7.91406H8.00469C7.7409 6.8348 6.76617 6.03125 5.60676 6.03125C4.44734 6.03125 3.47266 6.8348 3.20887 7.91406H0.585938C0.262344 7.91406 0 8.17641 0 8.5C0 8.82359 0.262344 9.08594 0.585938 9.08594H3.20887C3.47266 10.1652 4.44738 10.9688 5.6068 10.9688C6.76621 10.9688 7.74094 10.1652 8.00473 9.08594H19.4141C19.7377 9.08594 20 8.82359 20 8.5C20 8.17641 19.7377 7.91406 19.4141 7.91406ZM5.60676 9.79688C4.89164 9.79688 4.30988 9.21508 4.30988 8.5C4.30988 7.78492 4.89168 7.20312 5.60676 7.20312C6.32184 7.20312 6.90363 7.78492 6.90363 8.5C6.90363 9.21508 6.32188 9.79688 5.60676 9.79688Z" fill="#0A1F69"/>
<path d="M19.4141 13.5625H13.6531C13.3893 12.4833 12.4146 11.6797 11.2552 11.6797C10.0959 11.6797 9.12109 12.4832 8.8573 13.5625H0.585938C0.262344 13.5625 0 13.8249 0 14.1485C0 14.4721 0.262344 14.7344 0.585938 14.7344H8.8573C9.12109 15.8137 10.0958 16.6172 11.2552 16.6172C12.4146 16.6172 13.3893 15.8137 13.6531 14.7344H19.4141C19.7377 14.7344 20 14.4721 20 14.1485C20 13.8249 19.7377 13.5625 19.4141 13.5625ZM11.2552 15.4453C10.5401 15.4453 9.95836 14.8635 9.95836 14.1485C9.95836 13.4334 10.5402 12.8516 11.2552 12.8516C11.9703 12.8516 12.5521 13.4334 12.5521 14.1485C12.5521 14.8635 11.9703 15.4453 11.2552 15.4453Z" fill="#0A1F69"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,6 @@
<svg width="79" height="71" viewBox="0 0 79 71" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="46.5" cy="38" r="32.5" fill="#F2F5FF"/>
<path d="M66.6685 59.2848L63.3349 23.738C63.2996 23.3631 63.0772 23.0311 62.7434 22.8568L49.9643 16.1787C49.9406 16.1663 49.9132 16.1689 49.8888 16.1583C49.816 16.1268 49.7387 16.112 49.6586 16.0965C49.5815 16.0814 49.5086 16.0638 49.4304 16.0651C49.4129 16.0654 49.3978 16.0572 49.3799 16.0582C49.3169 16.0621 49.264 16.0913 49.2045 16.1052C49.1441 16.1191 49.0811 16.1132 49.023 16.1374L45.067 17.7819C44.5 18.0174 44.232 18.668 44.4674 19.2344C44.7034 19.8019 45.3529 20.0701 45.9199 19.834L48.4374 18.7875L50.5118 51.9502L34.4479 57.8008V34.7293C34.4479 34.1155 33.9503 33.6181 33.3367 33.6181C32.723 33.6181 32.2255 34.1157 32.2255 34.7293V57.8008L16.1616 51.9502L18.2361 18.7875L20.7535 19.834C21.321 20.0699 21.9711 19.8019 22.206 19.2344C22.4415 18.668 22.1735 18.0174 21.6065 17.7819L17.6505 16.1374C17.5926 16.1134 17.5299 16.1193 17.4697 16.1055C17.4099 16.0915 17.3567 16.0622 17.2934 16.0582C17.2757 16.0573 17.2606 16.0655 17.243 16.0654C17.1623 16.0639 17.087 16.0825 17.0074 16.0987C16.9329 16.1139 16.8607 16.1272 16.7924 16.1564C16.7655 16.1678 16.7353 16.1651 16.7091 16.1787L3.93003 22.8568C3.59641 23.0311 3.37386 23.3631 3.33857 23.738L0.0048901 59.2848C-0.0326138 59.6837 0.147613 60.0716 0.476423 60.3005C0.804191 60.5289 1.23275 60.5637 1.59255 60.3901L15.0613 53.9148L32.9565 60.4324C33.2017 60.5225 33.4719 60.5225 33.7172 60.4324L51.6124 53.9148L65.0811 60.3901C65.2336 60.4633 65.3986 60.4998 65.5624 60.4998C65.7854 60.4998 66.0079 60.4324 66.1973 60.3007C66.5258 60.0715 66.7059 59.6835 66.6685 59.2848ZM13.9321 51.9912L2.40071 57.5354L5.49452 24.547L15.9918 19.061L13.9321 51.9912ZM52.7409 51.9912L50.6812 19.061L61.1785 24.547L64.2723 57.5354L52.7409 51.9912Z" fill="#0A1F69"/>
<path d="M23.5455 16.259L32.3821 31.0685C32.5829 31.4048 32.9453 31.6104 33.3364 31.6104C33.7276 31.6104 34.09 31.4048 34.2908 31.0685L43.1514 16.2167C43.5779 15.4245 43.8633 14.7534 44.0489 14.1033C44.3141 13.1749 44.4488 12.2108 44.4488 11.2384C44.4488 9.7837 44.1531 8.37249 43.5693 7.04254C43.0071 5.76259 42.2025 4.61338 41.1792 3.62799C40.1592 2.64534 38.9709 1.87377 37.6485 1.33505C34.9138 0.221651 31.7592 0.221651 29.0245 1.33505C27.7023 1.87377 26.514 2.64547 25.4945 3.62799C24.4706 4.61338 23.6659 5.76259 23.1039 7.04306C22.5201 8.37236 22.2244 9.7837 22.2244 11.2384C22.2244 12.2108 22.3589 13.1749 22.6243 14.1038C22.8097 14.7532 23.0952 15.4244 23.5455 16.259ZM25.1386 7.93664C25.5836 6.92312 26.2222 6.01209 27.0361 5.22855C27.8522 4.4424 28.8033 3.82489 29.8624 3.39346C30.9628 2.94524 32.1315 2.71852 33.3366 2.71852C34.5417 2.71852 35.7104 2.94537 36.8108 3.39346C37.8699 3.82476 38.8211 4.44227 39.6376 5.22855C40.451 6.01209 41.0896 6.92299 41.5346 7.93612C41.9936 8.98219 42.2264 10.093 42.2264 11.2383C42.2264 12.0044 42.1207 12.7629 41.9123 13.4928C41.7718 13.9844 41.5439 14.5151 41.2189 15.1206L33.3366 28.3305L25.4782 15.1629C25.1294 14.5151 24.9015 13.9844 24.761 13.4933C24.5526 12.763 24.4469 12.0045 24.4469 11.2383C24.4467 10.093 24.6796 8.98219 25.1386 7.93664Z" fill="#0A1F69"/>
<path d="M33.3367 17.1678C36.4002 17.1678 38.8929 14.6751 38.8929 11.6116C38.8929 8.54812 36.4002 6.05542 33.3367 6.05542C30.2732 6.05542 27.7805 8.54812 27.7805 11.6116C27.7805 14.6751 30.2732 17.1678 33.3367 17.1678ZM33.3367 8.27791C35.175 8.27791 36.6704 9.77325 36.6704 11.6116C36.6704 13.4499 35.175 14.9453 33.3367 14.9453C31.4984 14.9453 30.003 13.4499 30.003 11.6116C30.003 9.77325 31.4984 8.27791 33.3367 8.27791Z" fill="#0A1F69"/>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,61 @@
<svg width="189" height="150" viewBox="0 0 189 150" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_68)">
<path d="M94.495 149.13C146.614 149.13 188.865 146.663 188.865 143.62C188.865 140.577 146.614 138.11 94.495 138.11C42.3759 138.11 0.125 140.577 0.125 143.62C0.125 146.663 42.3759 149.13 94.495 149.13Z" fill="#F0F6FF"/>
<path d="M131.285 2.53003H26.1949V105.43H131.285V2.53003Z" fill="#0F264C"/>
<path d="M128.585 5.82001H28.8949V105.43H128.585V5.82001Z" fill="white"/>
<path d="M131.285 103.98V105.43H78.325L89.775 93.99L105.535 78.22L131.285 103.98Z" fill="#0F264C"/>
<path d="M26.1949 105.43V95.54L58.7549 62.98L101.215 105.43H26.1949Z" fill="#0F264C"/>
<path d="M96.075 51.65C104.961 51.65 112.165 44.4463 112.165 35.56C112.165 26.6738 104.961 19.47 96.075 19.47C87.1887 19.47 79.985 26.6738 79.985 35.56C79.985 44.4463 87.1887 51.65 96.075 51.65Z" fill="#0F264C"/>
<path d="M150.287 7.86711L150.239 8.3548L153.723 8.69512L153.77 8.20744L150.287 7.86711Z" fill="#0053CC"/>
<path d="M138.447 6.7085L138.399 7.19617L146.909 8.02753L146.956 7.53986L138.447 6.7085Z" fill="#0053CC"/>
<path d="M57.363 0.505688L47.3574 102.918L151.949 113.137L161.955 10.7242L57.363 0.505688Z" fill="#0053CC"/>
<path d="M59.7374 4.04914L50.0518 103.187L149.269 112.881L158.955 13.7425L59.7374 4.04914Z" fill="white"/>
<path d="M152.085 111.69L151.945 113.13L99.235 107.98L111.735 97.71L128.955 83.55L152.085 111.69Z" fill="#0053CC"/>
<path d="M47.355 102.92L48.315 93.07L83.885 63.83L122.015 110.21L47.355 102.92Z" fill="#0053CC"/>
<path d="M138.424 46.6175C141.992 38.4788 138.286 28.989 130.148 25.4215C122.009 21.8539 112.519 25.5596 108.952 33.6982C105.384 41.8369 109.09 51.3267 117.228 54.8943C125.367 58.4618 134.857 54.7562 138.424 46.6175Z" fill="#0053CC"/>
<path d="M115.296 14.0952L10.4298 20.9501L17.1419 123.631L122.008 116.776L115.296 14.0952Z" fill="#9FC6FF"/>
<path d="M112.826 17.5571L13.3484 24.0598L19.8458 123.458L119.324 116.955L112.826 17.5571Z" fill="white"/>
<path d="M121.915 115.34L122.015 116.79L69.165 120.24L79.835 108.08L94.535 91.32L121.915 115.34Z" fill="#9FC6FF"/>
<path d="M17.145 123.64L16.495 113.77L46.865 79.15L91.995 118.75L17.145 123.64Z" fill="#9FC6FF"/>
<path d="M93.6987 60.7395C99.9822 54.4559 99.9822 44.2683 93.6987 37.9848C87.4152 31.7012 77.2275 31.7012 70.944 37.9848C64.6605 44.2683 64.6605 54.4559 70.944 60.7395C77.2275 67.023 87.4152 67.023 93.6987 60.7395Z" fill="#9FC6FF"/>
<path d="M157.355 65.8701L153.935 67.0001L157.025 70.3101C157.025 70.3101 159.725 68.7001 159.025 67.1801L157.355 65.8701Z" fill="#FFC3BD"/>
<path d="M151.595 70.05L154.265 72.63L157.025 70.32L153.935 67L151.595 70.05Z" fill="#FFC3BD"/>
<path d="M162.945 38.8201C163.295 39.4601 163.575 40.0301 163.865 40.6401C164.145 41.2401 164.425 41.8401 164.695 42.4501C165.215 43.6701 165.705 44.9101 166.135 46.1701C166.575 47.4301 166.945 48.7301 167.265 50.0501L167.495 51.0501L167.685 52.0701C167.755 52.4101 167.795 52.7601 167.835 53.1101L167.905 53.6301L167.925 53.7601L167.945 53.9801C167.965 54.1501 167.965 54.2901 167.965 54.4401C167.925 55.6101 167.625 56.3901 167.335 57.1301C167.025 57.8601 166.685 58.4901 166.325 59.1001C165.605 60.3101 164.805 61.3901 163.975 62.4401C162.315 64.5201 160.525 66.3901 158.575 68.1701L156.595 66.3901C158.015 64.3401 159.415 62.2301 160.685 60.1401C161.315 59.0901 161.905 58.0301 162.385 57.0001C162.625 56.4901 162.835 55.9701 162.975 55.5101C163.115 55.0601 163.185 54.6001 163.145 54.4801C163.145 54.4801 163.145 54.4601 163.135 54.4701C163.135 54.4701 163.135 54.5001 163.135 54.4501L163.115 54.3401L163.025 53.9201C162.965 53.6401 162.915 53.3601 162.825 53.0801L162.605 52.2301L162.355 51.3801C162.005 50.2501 161.605 49.1101 161.165 47.9801C160.725 46.8501 160.255 45.7301 159.755 44.6101C159.275 43.5001 158.725 42.3601 158.225 41.3301L162.975 38.8101L162.945 38.8201Z" fill="#FFC3BD"/>
<path d="M168.535 47.33L161.915 50.83L160.315 51.68C160.315 51.68 159.945 50.58 159.405 48.99C158.975 47.72 158.445 46.14 157.915 44.54C157.745 44.03 157.585 43.53 157.425 43.04C157.375 42.9 157.325 42.76 157.285 42.62C155.855 38.23 159.825 36.27 162.525 36.83C167.155 37.8 168.535 47.33 168.535 47.33Z" fill="#9FC6FF"/>
<path d="M161.905 50.83L160.305 51.68C160.305 51.68 159.935 50.58 159.395 48.99C158.965 47.72 158.435 46.14 157.905 44.54C157.735 44.03 157.575 43.53 157.415 43.04L161.065 42.32C161.065 42.32 161.565 48.11 161.895 50.83H161.905Z" fill="#77B3FC"/>
<path d="M157.255 26.79C156.495 29.32 155.515 34 157.155 35.9C157.155 35.9 156.185 38.45 151.395 37.97C146.115 37.45 149.135 35.1 149.135 35.1C152.085 34.7 152.225 32.56 151.915 30.5L157.255 26.78V26.79Z" fill="#FFC3BD"/>
<path d="M148.105 36.0001C148.345 35.5301 148.005 33.7801 148.005 33.7801C148.005 33.7801 155.535 32.7701 158.225 33.7301C159.675 34.2501 158.405 36.8501 158.405 36.8501L148.115 36.0001H148.105Z" fill="#14365B"/>
<path d="M148.265 22.9601C148.235 23.2401 148.065 23.4601 147.875 23.4401C147.685 23.4201 147.565 23.1801 147.585 22.8901C147.615 22.6101 147.785 22.3901 147.975 22.4101C148.165 22.4301 148.285 22.6701 148.265 22.9601Z" fill="#0F264C"/>
<path d="M148.255 23.1C148.255 23.1 147.445 24.68 146.655 25.4C147.115 25.92 147.985 25.79 147.985 25.79L148.255 23.1Z" fill="#ED847E"/>
<path d="M149.345 22.0201C149.285 22.0201 149.235 21.9901 149.205 21.9401C148.815 21.3001 148.195 21.2801 148.195 21.2801C148.105 21.2801 148.025 21.2001 148.035 21.1101C148.035 21.0201 148.105 20.9401 148.205 20.9501C148.235 20.9501 149.015 20.9801 149.495 21.7801C149.545 21.8601 149.515 21.9601 149.435 22.0101C149.405 22.0301 149.375 22.0301 149.345 22.0301V22.0201Z" fill="#0F264C"/>
<path d="M132.935 136.07L129.395 135.81L129.065 127.55L132.595 127.81L132.935 136.07Z" fill="#FFC3BD"/>
<path d="M155.535 139.23H151.985L149.225 131.01H152.775L155.535 139.23Z" fill="#FFC3BD"/>
<path d="M151.515 138.81H155.835C155.985 138.81 156.105 138.91 156.135 139.05L156.835 142.2C156.905 142.53 156.655 142.84 156.315 142.83C154.925 142.81 153.905 142.72 152.155 142.72C151.075 142.72 148.855 142.83 147.365 142.83C145.875 142.83 145.685 141.36 146.295 141.22C149.025 140.62 150.055 139.8 150.935 139.01C151.095 138.87 151.295 138.79 151.515 138.79V138.81Z" fill="#14365B"/>
<path d="M129.225 135.02L133.085 135.31C133.225 135.32 133.345 135.43 133.365 135.57L133.825 138.77C133.875 139.1 133.605 139.39 133.265 139.36C131.875 139.23 129.865 139 128.115 138.87C126.065 138.72 124.705 138.65 122.305 138.47C120.855 138.36 120.555 136.86 121.175 136.78C123.985 136.38 125.835 136.54 128.335 135.24C128.605 135.1 128.905 135.01 129.205 135.03L129.225 135.02Z" fill="#14365B"/>
<path d="M129.065 127.55L129.235 131.81L132.775 132.07L132.605 127.82L129.065 127.55Z" fill="#F29994"/>
<path d="M152.775 131.01H149.225L150.655 135.25H154.205L152.775 131.01Z" fill="#F29994"/>
<path d="M160.115 67.75C157.345 67.55 146.895 66.77 141.195 66.34C140.515 60.82 140.395 56.03 140.575 51.99C140.655 50.27 140.785 48.68 140.955 47.23C141.835 39.64 143.685 35.79 143.685 35.79C143.685 35.79 146.375 35.26 149.195 35.21C151.335 35.18 154.835 35.51 157.235 35.81C160.315 36.19 162.965 36.94 162.965 36.94C159.145 50.41 160.465 64.85 160.115 67.75Z" fill="#9FC6FF"/>
<path d="M142.865 48.69L140.585 52C140.665 50.28 140.795 48.6901 140.965 47.2401L142.865 48.7001V48.69Z" fill="#77B3FC"/>
<path d="M141.415 38.2401C141.095 38.7901 140.715 39.4201 140.355 40.0201C139.985 40.62 139.615 41.22 139.225 41.8C138.455 42.98 137.665 44.14 136.845 45.26C136.015 46.38 135.165 47.4601 134.265 48.4701C133.455 49.3701 132.615 50.2 131.745 50.91C130.995 51.08 130.235 51.1901 129.465 51.2401C128.505 51.2801 127.525 51.24 126.545 51.07C125.565 50.91 124.595 50.63 123.645 50.26C123.165 50.07 122.695 49.87 122.235 49.64C122.005 49.52 121.785 49.4001 121.555 49.2701C121.345 49.1501 121.095 49 120.945 48.91L119.085 50.82C119.355 51.12 119.545 51.3301 119.785 51.5601C120.015 51.7801 120.255 51.99 120.505 52.19C120.995 52.6 121.505 52.98 122.045 53.32C123.115 54.01 124.295 54.5701 125.525 54.9901C126.765 55.4001 128.065 55.66 129.395 55.75C130.715 55.83 132.055 55.76 133.355 55.5201L133.765 55.4501L134.225 55.1501C135.645 54.2101 136.875 53.1501 137.995 52.0201C139.115 50.9001 140.135 49.72 141.085 48.51C142.045 47.3 142.925 46.05 143.765 44.78C144.185 44.14 144.585 43.5 144.985 42.85C145.385 42.19 145.755 41.5601 146.145 40.8301L141.425 38.26L141.415 38.2401Z" fill="#FFC3BD"/>
<path d="M147.835 39.8701C147.585 43.2501 143.575 49.8301 143.575 49.8301L134.515 45.0701C134.515 45.0701 137.585 40.1401 140.935 37.2001C144.325 34.2301 148.105 36.1501 147.825 39.8601L147.835 39.8701Z" fill="#9FC6FF"/>
<path d="M122.535 50.0701L119.885 47.7601L117.845 51.2401C117.845 51.2401 119.725 53.3501 121.945 52.0201L122.535 50.0801V50.0701Z" fill="#FFC3BD"/>
<path d="M116.205 46.2101L114.795 49.4101L117.845 51.2301L119.885 47.7501L116.205 46.2101Z" fill="#FFC3BD"/>
<path d="M157.955 22.9401C157.395 26.4101 157.245 28.4801 155.295 30.1001C152.375 32.5401 148.215 30.5101 147.725 26.9301C147.285 23.7101 148.275 18.5701 151.835 17.5201C155.345 16.4801 158.505 19.4701 157.945 22.9401H157.955Z" fill="#FFC3BD"/>
<path d="M161.885 21.1101C164.485 22.9301 158.295 29.6101 156.095 29.5401C153.895 29.4701 149.785 23.3601 151.125 20.1201C149.985 19.6601 149.625 19.5101 149.165 18.3501C148.335 16.2501 149.335 12.7501 154.475 13.7301C153.195 14.6001 154.085 15.2801 156.505 14.9501C155.555 16.0901 157.125 16.9201 159.475 16.4401C159.065 18.5201 164.315 18.8201 161.885 21.1101Z" fill="#0F264C"/>
<path d="M153.065 24.0101C152.895 24.9401 152.315 25.7201 151.675 26.1501C150.705 26.8101 149.845 26.0301 149.805 24.9101C149.775 23.9101 150.235 22.3601 151.355 22.1501C152.465 21.9401 153.255 22.9301 153.065 24.0001V24.0101Z" fill="#FFC3BD"/>
<path d="M155.485 134.43H148.985C148.985 134.43 142.655 112.67 141.065 101.39C140.725 98.96 140.925 95.75 141.435 92.26C142.305 86.3 144.065 79.53 145.535 74.47C146.845 69.98 147.915 66.84 147.915 66.84C147.915 66.84 152.885 67.21 160.125 67.75C159.465 76.61 150.695 91.17 151.305 103.19C151.865 114.27 155.485 134.42 155.485 134.42V134.43Z" fill="#14365B"/>
<path d="M148.765 77.04C148.695 82.94 144.555 89.46 141.435 92.26C142.305 86.3 144.065 79.53 145.535 74.47C146.445 74.29 148.005 76.02 148.765 77.03V77.04Z" fill="#0A1B35"/>
<path d="M141.205 66.35C141.205 66.35 125.885 89.53 125.465 100.34C125.035 111.59 127.965 130.89 127.965 130.89L133.955 131.34C133.955 131.34 134.655 112.98 135.735 101.98C136.915 89.99 154.225 76.63 154.915 67.36C149.065 66.93 141.195 66.34 141.195 66.34L141.205 66.35Z" fill="#14365B"/>
<path d="M147.835 134.57H156.325V132.28L146.835 132.13L147.835 134.57Z" fill="#0053CC"/>
<path d="M126.765 130.93L135.085 131.57L135.255 129.26L125.945 128.43L126.765 130.93Z" fill="#0053CC"/>
<path d="M150.345 139.43C150.075 139.43 149.825 139.38 149.665 139.25C149.535 139.14 149.475 138.99 149.495 138.81C149.495 138.67 149.575 138.6 149.635 138.57C150.035 138.37 151.175 139.07 151.305 139.15C151.335 139.17 151.345 139.2 151.345 139.23C151.345 139.26 151.315 139.29 151.285 139.3C151.035 139.36 150.685 139.43 150.355 139.43H150.345ZM149.815 138.7C149.815 138.7 149.735 138.7 149.705 138.72C149.685 138.73 149.655 138.75 149.655 138.82C149.655 138.95 149.685 139.05 149.765 139.12C149.955 139.28 150.425 139.31 151.025 139.18C150.625 138.95 150.085 138.69 149.815 138.69V138.7Z" fill="#407BFF"/>
<path d="M151.255 139.31C151.255 139.31 151.225 139.31 151.215 139.3C150.845 139.1 150.135 138.32 150.215 137.93C150.225 137.86 150.285 137.73 150.485 137.71C150.615 137.69 150.735 137.73 150.845 137.82C151.255 138.16 151.345 139.18 151.345 139.22C151.345 139.25 151.335 139.28 151.305 139.3C151.295 139.3 151.275 139.31 151.255 139.31ZM150.535 137.87C150.535 137.87 150.505 137.87 150.495 137.87C150.385 137.88 150.375 137.93 150.375 137.96C150.335 138.19 150.785 138.78 151.145 139.06C151.105 138.76 150.995 138.16 150.725 137.95C150.665 137.9 150.605 137.88 150.535 137.88V137.87Z" fill="#407BFF"/>
<path d="M128.015 135.54C127.555 135.54 127.085 135.48 126.865 135.25C126.755 135.14 126.715 135 126.735 134.83C126.755 134.73 126.805 134.66 126.885 134.62C127.335 134.42 128.705 135.24 128.855 135.33C128.885 135.35 128.905 135.38 128.895 135.42C128.895 135.45 128.855 135.48 128.825 135.49C128.595 135.52 128.305 135.54 128.005 135.54H128.015ZM127.085 134.75C127.085 134.75 126.995 134.75 126.965 134.77C126.925 134.79 126.915 134.81 126.905 134.86C126.885 134.97 126.905 135.06 126.985 135.14C127.185 135.35 127.765 135.43 128.555 135.35C128.065 135.07 127.395 134.75 127.075 134.75H127.085Z" fill="#407BFF"/>
<path d="M128.815 135.48C128.815 135.48 128.785 135.48 128.775 135.47C128.365 135.25 127.575 134.42 127.665 134.02C127.685 133.93 127.765 133.82 127.995 133.81C128.165 133.81 128.315 133.87 128.445 133.99C128.865 134.39 128.895 135.35 128.895 135.39C128.895 135.42 128.885 135.45 128.855 135.46C128.845 135.46 128.825 135.47 128.815 135.47V135.48ZM128.015 133.98C128.015 133.98 128.015 133.98 128.005 133.98C127.855 133.98 127.835 134.04 127.835 134.06C127.775 134.3 128.305 134.94 128.725 135.23C128.705 134.95 128.615 134.37 128.335 134.1C128.245 134.01 128.135 133.97 128.015 133.97V133.98Z" fill="#407BFF"/>
</g>
<defs>
<clipPath id="clip0_1_68">
<rect width="188.75" height="148.63" fill="white" transform="translate(0.125 0.5)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,5 @@
<svg width="65" height="71" viewBox="0 0 65 71" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="32.5" cy="38" r="32.5" fill="#F2F5FF"/>
<path d="M34.8327 45.2796C39.8898 36.8918 46.2816 25.1 46.2816 19.0388C46.2816 8.81429 37.9673 0.5 27.7429 0.5C17.5184 0.5 9.20408 8.81429 9.20408 19.0388C9.20408 25.1 15.5959 36.8918 20.6531 45.2796C14.6531 45.7327 1 47.3612 1 52.7612C1 58.0755 14.8612 60.5 27.7551 60.5C40.6367 60.5 54.5102 58.0755 54.5102 52.7612C54.498 47.3612 40.8327 45.7327 34.8327 45.2796ZM11.7633 19.0388C11.7633 10.2224 18.9388 3.04694 27.7429 3.04694C36.5592 3.04694 43.7347 10.2224 43.7347 19.0388C43.7347 26.7408 31.4653 46.0633 27.7429 51.7449C24.0204 46.0633 11.7633 26.7408 11.7633 19.0388ZM27.7429 57.9408C12.0816 57.9408 3.54694 54.5122 3.54694 52.749C3.54694 51.3898 9.17959 48.4633 22.1592 47.7163C24.5959 51.6469 26.4449 54.4265 26.6898 54.7571C27.0204 55.198 27.9878 55.7245 28.8082 54.7571C29.0653 54.451 30.902 51.6469 33.3388 47.7163C46.3184 48.4633 51.951 51.3776 51.951 52.749C51.9388 54.5245 43.4041 57.9408 27.7429 57.9408Z" fill="#0A1F69"/>
<path d="M35.8121 19.0387C35.8121 14.5816 32.1999 10.9694 27.7427 10.9694C23.2856 10.9694 19.6733 14.5816 19.6733 19.0387C19.6733 23.4959 23.2856 27.1081 27.7427 27.1081C32.1999 27.1081 35.8121 23.4959 35.8121 19.0387ZM22.2203 19.0387C22.2203 15.9898 24.6937 13.5163 27.7427 13.5163C30.7917 13.5163 33.2652 15.9898 33.2652 19.0387C33.2652 22.0877 30.7917 24.5612 27.7427 24.5612C24.6937 24.5612 22.2203 22.0877 22.2203 19.0387Z" fill="#0A1F69"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,3 @@
<svg width="113" height="114" viewBox="0 0 113 114" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M56.5 0.5C25.2961 0.5 0 25.7961 0 57C0 88.2057 25.2961 113.5 56.5 113.5C87.7057 113.5 113 88.2057 113 57C113 25.7961 87.7057 0.5 56.5 0.5ZM56.5 106.549C29.2405 106.549 7.0625 84.2595 7.0625 56.9998C7.0625 29.7403 29.2405 7.56228 56.5 7.56228C83.7595 7.56228 105.938 29.7404 105.938 56.9998C105.938 84.2591 83.7595 106.549 56.5 106.549ZM79.0488 36.3263L45.8991 69.6842L30.9707 54.7559C29.5918 53.3769 27.3565 53.3769 25.9758 54.7559C24.5968 56.1348 24.5968 58.3701 25.9758 59.7491L43.4537 77.2288C44.8326 78.606 47.0679 78.606 48.4486 77.2288C48.6075 77.0699 48.7436 76.8967 48.8672 76.7167L84.0455 41.3211C85.4227 39.9422 85.4227 37.7069 84.0455 36.3263C82.6648 34.9473 80.4295 34.9473 79.0488 36.3263Z" fill="#68C149"/>
</svg>

After

Width:  |  Height:  |  Size: 837 B

View File

@@ -0,0 +1,61 @@
<svg width="189" height="150" viewBox="0 0 189 150" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5_57)">
<path d="M94.495 149.13C146.614 149.13 188.865 146.663 188.865 143.62C188.865 140.577 146.614 138.11 94.495 138.11C42.3759 138.11 0.125 140.577 0.125 143.62C0.125 146.663 42.3759 149.13 94.495 149.13Z" fill="#F0F6FF"/>
<path d="M131.285 2.52991H26.1951V105.43H131.285V2.52991Z" fill="#0F264C"/>
<path d="M128.585 5.81995H28.895V105.43H128.585V5.81995Z" fill="white"/>
<path d="M131.285 103.98V105.43H78.325L89.775 93.99L105.535 78.22L131.285 103.98Z" fill="#0F264C"/>
<path d="M26.1951 105.43V95.5399L58.7551 62.9799L101.215 105.43H26.1951Z" fill="#0F264C"/>
<path d="M96.0751 51.6498C104.961 51.6498 112.165 44.4461 112.165 35.5599C112.165 26.6736 104.961 19.4698 96.0751 19.4698C87.1888 19.4698 79.9851 26.6736 79.9851 35.5599C79.9851 44.4461 87.1888 51.6498 96.0751 51.6498Z" fill="#0F264C"/>
<path d="M150.287 7.86705L150.24 8.35474L153.723 8.69506L153.771 8.20738L150.287 7.86705Z" fill="#0053CC"/>
<path d="M138.447 6.70838L138.4 7.19604L146.909 8.02741L146.957 7.53974L138.447 6.70838Z" fill="#0053CC"/>
<path d="M57.3632 0.505566L47.3577 102.918L151.95 113.136L161.955 10.724L57.3632 0.505566Z" fill="#0053CC"/>
<path d="M59.7376 4.04914L50.052 103.187L149.27 112.881L158.955 13.7425L59.7376 4.04914Z" fill="white"/>
<path d="M152.085 111.69L151.945 113.13L99.2351 107.98L111.735 97.7099L128.955 83.5499L152.085 111.69Z" fill="#0053CC"/>
<path d="M47.3552 102.92L48.3152 93.07L83.8852 63.83L122.015 110.21L47.3552 102.92Z" fill="#0053CC"/>
<path d="M138.425 46.6174C141.992 38.4787 138.287 28.989 130.148 25.4214C122.009 21.8539 112.519 25.5595 108.952 33.6982C105.384 41.8369 109.09 51.3266 117.229 54.8942C125.367 58.4617 134.857 54.7561 138.425 46.6174Z" fill="#0053CC"/>
<path d="M115.296 14.0952L10.4299 20.9501L17.142 123.631L122.008 116.776L115.296 14.0952Z" fill="#9FC6FF"/>
<path d="M112.826 17.5571L13.3486 24.0598L19.8461 123.458L119.324 116.955L112.826 17.5571Z" fill="white"/>
<path d="M121.915 115.34L122.015 116.79L69.165 120.24L79.835 108.08L94.535 91.3201L121.915 115.34Z" fill="#9FC6FF"/>
<path d="M17.1451 123.64L16.4951 113.77L46.8651 79.15L91.9951 118.75L17.1451 123.64Z" fill="#9FC6FF"/>
<path d="M93.6987 60.7395C99.9822 54.456 99.9822 44.2684 93.6987 37.9848C87.4152 31.7013 77.2275 31.7013 70.944 37.9848C64.6605 44.2684 64.6605 54.456 70.944 60.7395C77.2275 67.0231 87.4152 67.0231 93.6987 60.7395Z" fill="#9FC6FF"/>
<path d="M157.355 65.87L153.935 67L157.025 70.31C157.025 70.31 159.725 68.7 159.025 67.18L157.355 65.87Z" fill="#FFC3BD"/>
<path d="M151.595 70.05L154.265 72.63L157.025 70.32L153.935 67L151.595 70.05Z" fill="#FFC3BD"/>
<path d="M162.945 38.8201C163.295 39.4601 163.575 40.0301 163.865 40.6401C164.145 41.2401 164.425 41.8401 164.695 42.4501C165.215 43.6701 165.705 44.9101 166.135 46.1701C166.575 47.4301 166.945 48.7301 167.265 50.0501L167.495 51.0501L167.685 52.0701C167.755 52.4101 167.795 52.7601 167.835 53.1101L167.905 53.6301L167.925 53.7601L167.945 53.9801C167.965 54.1501 167.965 54.2901 167.965 54.4401C167.925 55.6101 167.625 56.3901 167.335 57.1301C167.025 57.8601 166.685 58.4901 166.325 59.1001C165.605 60.3101 164.805 61.3901 163.975 62.4401C162.315 64.5201 160.525 66.3901 158.575 68.1701L156.595 66.3901C158.015 64.3401 159.415 62.2301 160.685 60.1401C161.315 59.0901 161.905 58.0301 162.385 57.0001C162.625 56.4901 162.835 55.9701 162.975 55.5101C163.115 55.0601 163.185 54.6001 163.145 54.4801C163.145 54.4801 163.145 54.4601 163.135 54.4701C163.135 54.4701 163.135 54.5001 163.135 54.4501L163.115 54.3401L163.025 53.9201C162.965 53.6401 162.915 53.3601 162.825 53.0801L162.605 52.2301L162.355 51.3801C162.005 50.2501 161.605 49.1101 161.165 47.9801C160.725 46.8501 160.255 45.7301 159.755 44.6101C159.275 43.5001 158.725 42.3601 158.225 41.3301L162.975 38.8101L162.945 38.8201Z" fill="#FFC3BD"/>
<path d="M168.535 47.33L161.915 50.83L160.315 51.68C160.315 51.68 159.945 50.58 159.405 48.99C158.975 47.72 158.445 46.14 157.915 44.54C157.745 44.03 157.585 43.53 157.425 43.04C157.375 42.9 157.325 42.76 157.285 42.62C155.855 38.23 159.825 36.27 162.525 36.83C167.155 37.8 168.535 47.33 168.535 47.33Z" fill="#9FC6FF"/>
<path d="M161.905 50.8301L160.305 51.6801C160.305 51.6801 159.935 50.5801 159.395 48.9901C158.965 47.7201 158.435 46.1401 157.905 44.5401C157.735 44.0301 157.575 43.5301 157.415 43.0401L161.065 42.3201C161.065 42.3201 161.565 48.1101 161.895 50.8301H161.905Z" fill="#77B3FC"/>
<path d="M157.255 26.79C156.495 29.32 155.515 34 157.155 35.9C157.155 35.9 156.185 38.45 151.395 37.97C146.115 37.45 149.135 35.1 149.135 35.1C152.085 34.7 152.225 32.56 151.915 30.5L157.255 26.78V26.79Z" fill="#FFC3BD"/>
<path d="M148.105 36C148.345 35.53 148.005 33.78 148.005 33.78C148.005 33.78 155.535 32.77 158.225 33.73C159.675 34.25 158.405 36.85 158.405 36.85L148.115 36H148.105Z" fill="#14365B"/>
<path d="M148.265 22.96C148.235 23.24 148.065 23.46 147.875 23.44C147.685 23.42 147.565 23.18 147.585 22.89C147.615 22.61 147.785 22.39 147.975 22.41C148.165 22.43 148.285 22.67 148.265 22.96Z" fill="#0F264C"/>
<path d="M148.255 23.1C148.255 23.1 147.445 24.68 146.655 25.4C147.115 25.92 147.985 25.79 147.985 25.79L148.255 23.1Z" fill="#ED847E"/>
<path d="M149.345 22.0199C149.285 22.0199 149.235 21.9899 149.205 21.9399C148.815 21.2999 148.195 21.2799 148.195 21.2799C148.105 21.2799 148.025 21.1999 148.035 21.1099C148.035 21.0199 148.105 20.9399 148.205 20.9499C148.235 20.9499 149.015 20.9799 149.495 21.7799C149.545 21.8599 149.515 21.9599 149.435 22.0099C149.405 22.0299 149.375 22.0299 149.345 22.0299V22.0199Z" fill="#0F264C"/>
<path d="M132.935 136.07L129.395 135.81L129.065 127.55L132.595 127.81L132.935 136.07Z" fill="#FFC3BD"/>
<path d="M155.535 139.23H151.985L149.225 131.01H152.775L155.535 139.23Z" fill="#FFC3BD"/>
<path d="M151.515 138.81H155.835C155.985 138.81 156.105 138.91 156.135 139.05L156.835 142.2C156.905 142.53 156.655 142.84 156.315 142.83C154.925 142.81 153.905 142.72 152.155 142.72C151.075 142.72 148.855 142.83 147.365 142.83C145.875 142.83 145.685 141.36 146.295 141.22C149.025 140.62 150.055 139.8 150.935 139.01C151.095 138.87 151.295 138.79 151.515 138.79V138.81Z" fill="#14365B"/>
<path d="M129.225 135.02L133.085 135.31C133.225 135.32 133.345 135.43 133.365 135.57L133.825 138.77C133.875 139.1 133.605 139.39 133.265 139.36C131.875 139.23 129.865 139 128.115 138.87C126.065 138.72 124.705 138.65 122.305 138.47C120.855 138.36 120.555 136.86 121.175 136.78C123.985 136.38 125.835 136.54 128.335 135.24C128.605 135.1 128.905 135.01 129.205 135.03L129.225 135.02Z" fill="#14365B"/>
<path d="M129.065 127.55L129.235 131.81L132.775 132.07L132.605 127.82L129.065 127.55Z" fill="#F29994"/>
<path d="M152.775 131.01H149.225L150.655 135.25H154.205L152.775 131.01Z" fill="#F29994"/>
<path d="M160.115 67.75C157.345 67.55 146.895 66.77 141.195 66.34C140.515 60.82 140.395 56.03 140.575 51.99C140.655 50.27 140.785 48.68 140.955 47.23C141.835 39.64 143.685 35.79 143.685 35.79C143.685 35.79 146.375 35.26 149.195 35.21C151.335 35.18 154.835 35.51 157.235 35.81C160.315 36.19 162.965 36.94 162.965 36.94C159.145 50.41 160.465 64.85 160.115 67.75Z" fill="#9FC6FF"/>
<path d="M142.865 48.69L140.585 52C140.665 50.28 140.795 48.69 140.965 47.24L142.865 48.7V48.69Z" fill="#77B3FC"/>
<path d="M141.415 38.24C141.095 38.79 140.715 39.42 140.355 40.02C139.985 40.62 139.615 41.22 139.225 41.8C138.455 42.98 137.665 44.14 136.845 45.26C136.015 46.38 135.165 47.46 134.265 48.47C133.455 49.37 132.615 50.2 131.745 50.91C130.995 51.08 130.235 51.19 129.465 51.24C128.505 51.28 127.525 51.24 126.545 51.07C125.565 50.91 124.595 50.63 123.645 50.26C123.165 50.07 122.695 49.87 122.235 49.64C122.005 49.52 121.785 49.4 121.555 49.27C121.345 49.15 121.095 49 120.945 48.91L119.085 50.82C119.355 51.12 119.545 51.33 119.785 51.56C120.015 51.78 120.255 51.99 120.505 52.19C120.995 52.6 121.505 52.98 122.045 53.32C123.115 54.01 124.295 54.57 125.525 54.99C126.765 55.4 128.065 55.66 129.395 55.75C130.715 55.83 132.055 55.76 133.355 55.52L133.765 55.45L134.225 55.15C135.645 54.21 136.875 53.15 137.995 52.02C139.115 50.9 140.135 49.72 141.085 48.51C142.045 47.3 142.925 46.05 143.765 44.78C144.185 44.14 144.585 43.5 144.985 42.85C145.385 42.19 145.755 41.56 146.145 40.83L141.425 38.26L141.415 38.24Z" fill="#FFC3BD"/>
<path d="M147.835 39.87C147.585 43.25 143.575 49.83 143.575 49.83L134.515 45.07C134.515 45.07 137.585 40.14 140.935 37.2C144.325 34.23 148.105 36.15 147.825 39.86L147.835 39.87Z" fill="#9FC6FF"/>
<path d="M122.535 50.07L119.885 47.76L117.845 51.24C117.845 51.24 119.725 53.35 121.945 52.02L122.535 50.08V50.07Z" fill="#FFC3BD"/>
<path d="M116.205 46.21L114.795 49.41L117.845 51.23L119.885 47.75L116.205 46.21Z" fill="#FFC3BD"/>
<path d="M157.955 22.94C157.395 26.41 157.245 28.48 155.295 30.1C152.375 32.54 148.215 30.51 147.725 26.93C147.285 23.71 148.275 18.57 151.835 17.52C155.345 16.48 158.505 19.47 157.945 22.94H157.955Z" fill="#FFC3BD"/>
<path d="M161.885 21.11C164.485 22.93 158.295 29.61 156.095 29.54C153.895 29.47 149.785 23.36 151.125 20.12C149.985 19.66 149.625 19.51 149.165 18.35C148.335 16.25 149.335 12.75 154.475 13.73C153.195 14.6 154.085 15.28 156.505 14.95C155.555 16.09 157.125 16.92 159.475 16.44C159.065 18.52 164.315 18.82 161.885 21.11Z" fill="#0F264C"/>
<path d="M153.065 24.0099C152.895 24.9399 152.315 25.7199 151.675 26.1499C150.705 26.8099 149.845 26.0299 149.805 24.9099C149.775 23.9099 150.235 22.3599 151.355 22.1499C152.465 21.9399 153.255 22.9299 153.065 23.9999V24.0099Z" fill="#FFC3BD"/>
<path d="M155.485 134.43H148.985C148.985 134.43 142.655 112.67 141.065 101.39C140.725 98.96 140.925 95.75 141.435 92.26C142.305 86.3 144.065 79.53 145.535 74.47C146.845 69.98 147.915 66.84 147.915 66.84C147.915 66.84 152.885 67.21 160.125 67.75C159.465 76.61 150.695 91.17 151.305 103.19C151.865 114.27 155.485 134.42 155.485 134.42V134.43Z" fill="#14365B"/>
<path d="M148.765 77.04C148.695 82.94 144.555 89.46 141.435 92.26C142.305 86.3 144.065 79.53 145.535 74.47C146.445 74.29 148.005 76.02 148.765 77.03V77.04Z" fill="#0A1B35"/>
<path d="M141.205 66.35C141.205 66.35 125.885 89.53 125.465 100.34C125.035 111.59 127.965 130.89 127.965 130.89L133.955 131.34C133.955 131.34 134.655 112.98 135.735 101.98C136.915 89.99 154.225 76.63 154.915 67.36C149.065 66.93 141.195 66.34 141.195 66.34L141.205 66.35Z" fill="#14365B"/>
<path d="M147.835 134.57H156.325V132.28L146.835 132.13L147.835 134.57Z" fill="#0053CC"/>
<path d="M126.765 130.93L135.085 131.57L135.255 129.26L125.945 128.43L126.765 130.93Z" fill="#0053CC"/>
<path d="M150.345 139.43C150.075 139.43 149.825 139.38 149.665 139.25C149.535 139.14 149.475 138.99 149.495 138.81C149.495 138.67 149.575 138.6 149.635 138.57C150.035 138.37 151.175 139.07 151.305 139.15C151.335 139.17 151.345 139.2 151.345 139.23C151.345 139.26 151.315 139.29 151.285 139.3C151.035 139.36 150.685 139.43 150.355 139.43H150.345ZM149.815 138.7C149.815 138.7 149.735 138.7 149.705 138.72C149.685 138.73 149.655 138.75 149.655 138.82C149.655 138.95 149.685 139.05 149.765 139.12C149.955 139.28 150.425 139.31 151.025 139.18C150.625 138.95 150.085 138.69 149.815 138.69V138.7Z" fill="#407BFF"/>
<path d="M151.255 139.31C151.255 139.31 151.225 139.31 151.215 139.3C150.845 139.1 150.135 138.32 150.215 137.93C150.225 137.86 150.285 137.73 150.485 137.71C150.615 137.69 150.735 137.73 150.845 137.82C151.255 138.16 151.345 139.18 151.345 139.22C151.345 139.25 151.335 139.28 151.305 139.3C151.295 139.3 151.275 139.31 151.255 139.31ZM150.535 137.87C150.535 137.87 150.505 137.87 150.495 137.87C150.385 137.88 150.375 137.93 150.375 137.96C150.335 138.19 150.785 138.78 151.145 139.06C151.105 138.76 150.995 138.16 150.725 137.95C150.665 137.9 150.605 137.88 150.535 137.88V137.87Z" fill="#407BFF"/>
<path d="M128.015 135.54C127.555 135.54 127.085 135.48 126.865 135.25C126.755 135.14 126.715 135 126.735 134.83C126.755 134.73 126.805 134.66 126.885 134.62C127.335 134.42 128.705 135.24 128.855 135.33C128.885 135.35 128.905 135.38 128.895 135.42C128.895 135.45 128.855 135.48 128.825 135.49C128.595 135.52 128.305 135.54 128.005 135.54H128.015ZM127.085 134.75C127.085 134.75 126.995 134.75 126.965 134.77C126.925 134.79 126.915 134.81 126.905 134.86C126.885 134.97 126.905 135.06 126.985 135.14C127.185 135.35 127.765 135.43 128.555 135.35C128.065 135.07 127.395 134.75 127.075 134.75H127.085Z" fill="#407BFF"/>
<path d="M128.815 135.48C128.815 135.48 128.785 135.48 128.775 135.47C128.365 135.25 127.575 134.42 127.665 134.02C127.685 133.93 127.765 133.82 127.995 133.81C128.165 133.81 128.315 133.87 128.445 133.99C128.865 134.39 128.895 135.35 128.895 135.39C128.895 135.42 128.885 135.45 128.855 135.46C128.845 135.46 128.825 135.47 128.815 135.47V135.48ZM128.015 133.98C128.015 133.98 128.015 133.98 128.005 133.98C127.855 133.98 127.835 134.04 127.835 134.06C127.775 134.3 128.305 134.94 128.725 135.23C128.705 134.95 128.615 134.37 128.335 134.1C128.245 134.01 128.135 133.97 128.015 133.97V133.98Z" fill="#407BFF"/>
</g>
<defs>
<clipPath id="clip0_5_57">
<rect width="188.75" height="148.63" fill="white" transform="translate(0.125 0.5)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

View File

@@ -0,0 +1,65 @@
<svg width="81" height="158" viewBox="0 0 81 158" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_1028)">
<path d="M40.5 157.5C62.5914 157.5 80.5 156.415 80.5 155.077C80.5 153.739 62.5914 152.654 40.5 152.654C18.4086 152.654 0.5 153.739 0.5 155.077C0.5 156.415 18.4086 157.5 40.5 157.5Z" fill="#F5F5F5"/>
<path d="M29.6244 152.173L25.9674 150.929L27.7777 141.822L31.4348 143.067L29.6244 152.173Z" fill="#FFB573"/>
<path d="M61.4325 152.221H57.5844L56.6246 142.982H60.4727L61.4325 152.221Z" fill="#FFB573"/>
<path d="M57.2659 151.759H61.9601C62.1192 151.759 62.2557 151.872 62.2875 152.032L63.0472 155.577C63.1245 155.944 62.847 156.293 62.4831 156.284C60.973 156.256 59.8723 156.166 57.971 156.166C56.802 156.166 53.2723 156.293 51.6576 156.293C50.0428 156.293 49.8291 154.639 50.4931 154.488C53.4588 153.814 55.6921 152.89 56.6428 152.004C56.8156 151.844 57.0385 151.759 57.2659 151.759Z" fill="#263238"/>
<path d="M26.031 150.33L30.0837 151.49C30.2338 151.532 30.3385 151.679 30.3294 151.844L30.152 155.473C30.1338 155.85 29.7835 156.109 29.4378 156.006C27.9823 155.563 25.8945 154.87 24.0569 154.347C21.91 153.734 21.5097 153.522 18.9898 152.8C17.466 152.367 17.466 150.651 18.1438 150.684C21.2232 150.854 22.1238 151.264 25.0576 150.378C25.376 150.283 25.7126 150.241 26.031 150.335V150.33Z" fill="#263238"/>
<path d="M44.994 31.0308C44.7484 31.3655 44.5573 31.6059 44.339 31.884C44.1298 32.1527 43.9114 32.4119 43.6931 32.6664C43.2564 33.1802 42.8107 33.6799 42.3513 34.1701C41.4416 35.16 40.4682 36.0886 39.4402 36.9795C37.3751 38.7377 35.0872 40.364 32.2762 41.3916C31.5757 41.6461 30.8343 41.8488 30.0611 41.9808C29.8655 42.0138 29.6744 42.0468 29.4789 42.0703L28.8784 42.1269C28.7147 42.1505 28.4008 42.1505 28.1234 42.1457C27.8687 42.1269 27.6049 42.1033 27.382 42.0609C26.4632 41.9006 25.7399 41.6084 25.0622 41.3067C24.389 41.005 23.7795 40.6656 23.1973 40.3027C22.0329 39.5862 20.9731 38.799 19.9633 37.96C18.949 37.1209 18.0119 36.2489 17.0931 35.2731L18.8398 32.8833C20.9776 33.9863 23.1609 35.1412 25.2532 35.9802C25.7763 36.1829 26.2903 36.3667 26.7725 36.5081C27.2501 36.6495 27.7186 36.725 28.0233 36.7297C28.1006 36.7297 28.1507 36.7203 28.2007 36.7203C28.2326 36.7061 28.228 36.7108 28.369 36.6825L28.6874 36.626L29.0149 36.5458C29.2287 36.5034 29.4561 36.4091 29.6744 36.3432C29.8973 36.2489 30.1202 36.1782 30.3476 36.0698C31.2528 35.6832 32.1625 35.1412 33.0449 34.5001C33.9364 33.8779 34.8052 33.152 35.6512 32.3789C36.5018 31.6106 37.316 30.781 38.1166 29.9325C38.5168 29.5035 38.908 29.0699 39.2855 28.6268L39.8496 27.9622L40.3681 27.3305L44.9894 31.0261L44.994 31.0308Z" fill="#FFB573"/>
<path d="M47.1044 29.0557C47.391 32.8597 39.1263 40.6185 39.1263 40.6185L31.8213 34.0523C31.8213 34.0523 34.8961 30.6773 38.353 27.2834C40.7274 24.9454 46.7951 24.9454 47.1044 29.0557Z" fill="white"/>
<path opacity="0.4" d="M47.1044 29.0557C47.391 32.8597 39.1263 40.6185 39.1263 40.6185L31.8213 34.0523C31.8213 34.0523 34.8961 30.6773 38.353 27.2834C40.7274 24.9454 46.7951 24.9454 47.1044 29.0557Z" fill="#407BFF"/>
<path opacity="0.2" d="M43.3837 31.0119C39.9859 31.3325 37.8163 34.1607 36.8702 37.2859C36.7656 37.6347 36.6746 37.993 36.6018 38.3465L39.1308 40.6185C39.1308 40.6185 42.8879 37.0879 45.2486 33.6233C45.3669 31.983 44.9166 30.8705 43.3837 31.0119Z" fill="black"/>
<path d="M19.7313 34.5755L18.4804 31.2853L14.2139 32.6429C14.2139 32.6429 15.6649 34.2691 17.2705 35.4004L19.7313 34.5755Z" fill="#FFB573"/>
<path d="M16.329 28.7116L12.813 30.1776L14.2139 32.6429L18.485 31.2853L16.329 28.7116Z" fill="#FFB573"/>
<path opacity="0.2" d="M27.7777 141.827L26.6906 147.29L30.4022 148.271L31.4347 143.071L27.7777 141.827Z" fill="black"/>
<path opacity="0.2" d="M60.4773 142.986H56.6246L57.1204 147.747H60.9731L60.4773 142.986Z" fill="black"/>
<path d="M62.747 27.2174C61.5598 31.6247 60.8002 36.1122 60.2999 40.3404C59.936 43.4326 59.7176 46.3787 59.5812 49.0561C59.2628 55.3253 59.3947 60.105 59.2128 61.7266C56.2016 61.5097 44.8621 60.6943 38.676 60.2464C35.8787 37.5593 41.2187 25.8646 41.2187 25.8646C41.2187 25.8646 43.493 25.3932 46.1357 25.2329C46.4814 25.2093 46.8361 25.1952 47.1955 25.1905C49.5198 25.1386 53.3133 25.5016 55.9287 25.8221C56.4791 25.8881 57.034 25.973 57.5753 26.0625C60.3272 26.5245 62.747 27.2221 62.747 27.2221V27.2174Z" fill="white"/>
<path opacity="0.4" d="M62.747 27.2174C61.5598 31.6247 60.8002 36.1122 60.2999 40.3404C59.936 43.4326 59.7176 46.3787 59.5812 49.0561C59.2628 55.3253 59.3947 60.105 59.2128 61.7266C56.2016 61.5097 44.8621 60.6943 38.676 60.2464C35.8787 37.5593 41.2187 25.8646 41.2187 25.8646C41.2187 25.8646 43.493 25.3932 46.1357 25.2329C46.4814 25.2093 46.8361 25.1952 47.1955 25.1905C49.5198 25.1386 53.3133 25.5016 55.9287 25.8221C56.4791 25.8881 57.034 25.973 57.5753 26.0625C60.3272 26.5245 62.747 27.2221 62.747 27.2221V27.2174Z" fill="#407BFF"/>
<path opacity="0.2" d="M57.5617 32.9587C57.548 36.527 58.4987 39.5391 60.1043 42.1787C60.1634 41.5707 60.2317 40.9579 60.3044 40.3404C60.5774 38.0165 60.9321 35.6125 61.4007 33.185L57.5662 32.9587H57.5617Z" fill="black"/>
<path d="M55.7513 15.5698C55.0054 18.4404 54.0956 23.7339 55.9287 25.8174C54.3822 27.2504 52.1625 28.4052 49.0104 28.1036C46.5951 27.8726 46.5951 26.1144 47.1955 25.1858C50.3795 24.639 50.4613 22.2208 50.0702 19.9205L55.7468 15.5651L55.7513 15.5698Z" fill="#FFB573"/>
<path opacity="0.2" d="M53.4361 17.3421L50.0747 19.9158C50.1702 20.4626 50.2339 21.0094 50.2339 21.5421C51.4438 21.4478 53.1768 20.2081 53.3906 18.9165C53.4998 18.2754 53.5134 17.6485 53.4315 17.3421H53.4361Z" fill="black"/>
<path d="M49.6471 11.2756C48.7374 12.6096 46.354 10.1537 46.4404 7.94768C49.9019 7.4716 48.2507 4.85548 51.3983 5.52483C54.0092 6.08105 50.6433 9.81432 49.6471 11.2756Z" fill="#263238"/>
<path d="M58.2666 12.1382C57.1068 15.9092 56.6155 18.1812 54.273 19.6613C50.7433 21.8862 46.6087 18.9401 46.6542 14.8863C46.6951 11.2379 48.5828 5.68038 52.5719 5.10059C56.5018 4.53023 59.4265 8.3672 58.2666 12.1429V12.1382Z" fill="#FFB573"/>
<path d="M56.0788 15.5698C56.0788 15.5698 55.7604 13.8823 55.9287 12.7368C56.0924 11.6527 56.5973 10.5968 56.5973 10.5968C56.5973 10.5968 54.4185 9.26281 54.3685 7.65543C54.3685 7.65543 50.4704 8.848 48.3963 7.03322C46.3176 5.21844 48.1734 3.11612 47.109 2.31478C49.6562 2.05553 50.4295 3.66291 52.0396 3.31409C53.5907 2.97942 52.2261 1.79156 52.4399 0.5C57.2932 4.83191 59.4038 2.8003 61.7599 5.27972C63.2655 6.86353 61.6826 9.83789 61.6826 9.83789C61.6826 9.83789 64.0842 14.0708 56.0788 15.5698Z" fill="#263238"/>
<path d="M60.9139 9.7389C60.9139 9.7389 63.2974 10.248 63.3611 7.66014C64.5892 10.2951 63.0518 10.6864 60.9139 9.7389Z" fill="#263238"/>
<path d="M50.1565 15.7348C51.6848 16.1213 52.64 15.2162 52.681 15.1738C52.7219 15.1361 52.7219 15.0701 52.681 15.0324C52.6446 14.99 52.5809 14.99 52.5445 15.0277C52.5354 15.0371 51.6211 15.8997 50.202 15.5368C50.1474 15.5226 50.0974 15.5556 50.0837 15.6122C50.0701 15.664 50.1019 15.7206 50.152 15.7348H50.1565Z" fill="#263238"/>
<path d="M58.908 16.3051C58.1711 17.0499 57.1705 17.3704 56.3244 17.3421C55.0508 17.3044 54.7916 16.027 55.4647 14.99C56.0697 14.0567 57.457 12.9489 58.5805 13.491C59.6904 14.0284 59.754 15.4519 58.908 16.3051Z" fill="#FFB573"/>
<path d="M25.6671 145.329L31.9487 147.12C31.9487 147.12 39.8177 121.416 41.7508 107.299C42.2648 103.556 43.0562 98.2909 44.2616 92.6816C45.7854 85.611 47.7003 77.97 49.265 71.9836C50.9161 65.6814 52.1761 61.2175 52.1761 61.2175L38.676 60.2417C38.676 60.2417 33.1495 91.5833 31.8577 103.683C30.5159 116.264 25.6671 145.329 25.6671 145.329Z" fill="#407BFF"/>
<path opacity="0.3" d="M25.6671 145.329L31.9487 147.12C31.9487 147.12 39.8177 121.416 41.7508 107.299C42.2648 103.556 43.0562 98.2909 44.2616 92.6816C45.7854 85.611 47.7003 77.97 49.265 71.9836C50.9161 65.6814 52.1761 61.2175 52.1761 61.2175L38.676 60.2417C38.676 60.2417 33.1495 91.5833 31.8577 103.683C30.5159 116.264 25.6671 145.329 25.6671 145.329Z" fill="black"/>
<path opacity="0.2" d="M44.2662 92.6769C45.79 85.6063 47.7049 77.9653 49.2696 71.9789L47.8687 68.8537C44.5209 72.9782 43.6203 85.743 44.2662 92.6769Z" fill="black"/>
<path d="M45.9628 60.765C45.9628 60.765 47.4183 94.9159 49.0467 106.479C50.8252 119.144 55.3464 146.823 55.3464 146.823H62.3967C62.3967 146.823 60.0633 117.697 59.0353 105.263C57.8618 91.1025 59.2218 61.7218 59.2218 61.7218L45.9719 60.765H45.9628Z" fill="#407BFF"/>
<path opacity="0.3" d="M45.9628 60.765C45.9628 60.765 47.4183 94.9159 49.0467 106.479C50.8252 119.144 55.3464 146.823 55.3464 146.823H62.3967C62.3967 146.823 60.0633 117.697 59.0353 105.263C57.8618 91.1025 59.2218 61.7218 59.2218 61.7218L45.9719 60.765H45.9628Z" fill="black"/>
<path d="M54.5004 146.984H62.8015V144.415L53.5179 144.245L54.5004 146.984Z" fill="#407BFF"/>
<path d="M25.235 145.367L32.3262 147.394L33.3496 144.858L25.2623 142.539L25.235 145.367Z" fill="#407BFF"/>
<path d="M52.399 11.7469C52.3217 12.058 52.1034 12.2702 51.9032 12.2183C51.7076 12.1665 51.6076 11.8742 51.6849 11.5584C51.7622 11.2426 51.9805 11.0352 52.1807 11.087C52.3808 11.1389 52.4763 11.4311 52.399 11.7469Z" fill="#263238"/>
<path d="M48.9921 10.8561C48.9148 11.1672 48.6965 11.3793 48.5009 11.3274C48.3053 11.2756 48.2052 10.9833 48.2825 10.6675C48.3599 10.3564 48.5782 10.1443 48.7783 10.1961C48.9739 10.248 49.074 10.5402 48.9967 10.8561H48.9921Z" fill="#263238"/>
<path d="M50.0384 11.2944C50.0384 11.2944 48.9149 12.9159 47.9506 13.59C48.3599 14.2452 49.3788 14.1745 49.3788 14.1745L50.0338 11.2944H50.0384Z" fill="#ED893E"/>
<path d="M53.7317 10.8796C53.6635 10.8749 53.6044 10.8325 53.5771 10.7665C53.2587 9.98873 52.5991 9.86146 52.5946 9.86146C52.4945 9.8426 52.4308 9.74361 52.449 9.63991C52.4672 9.53621 52.5582 9.4655 52.6628 9.48907C52.6992 9.49378 53.527 9.65876 53.9182 10.6204C53.9591 10.7146 53.9182 10.8278 53.8227 10.8702C53.7954 10.8843 53.7681 10.889 53.7408 10.8843L53.7317 10.8796Z" fill="#263238"/>
<path d="M47.8323 9.26281C47.7959 9.26281 47.7595 9.24396 47.7276 9.22039C47.6503 9.1544 47.6412 9.03184 47.7049 8.95642C48.3553 8.15509 49.1877 8.24936 49.2241 8.25408C49.3242 8.26822 49.397 8.36249 49.3833 8.46619C49.3697 8.5699 49.2741 8.6406 49.1832 8.63118C49.1559 8.63118 48.5054 8.56047 47.9824 9.19682C47.9414 9.24396 47.8868 9.26753 47.8277 9.26281H47.8323Z" fill="#263238"/>
<path d="M55.9923 152.456C55.7012 152.456 55.4238 152.404 55.2509 152.254C55.1145 152.136 55.0508 151.966 55.0644 151.754C55.0735 151.598 55.1554 151.523 55.2191 151.485C55.6466 151.259 56.8884 152.051 57.0249 152.141C57.0567 152.159 57.0703 152.197 57.0658 152.235C57.0612 152.272 57.034 152.301 56.9976 152.31C56.7292 152.376 56.3471 152.452 55.9923 152.452V152.456ZM55.4192 151.631C55.3737 151.631 55.3328 151.641 55.301 151.655C55.2782 151.669 55.2464 151.693 55.2418 151.768C55.2327 151.919 55.2737 152.032 55.3646 152.112C55.5739 152.296 56.0788 152.32 56.7292 152.183C56.2971 151.924 55.7103 151.631 55.4147 151.631H55.4192Z" fill="#407BFF"/>
<path d="M56.9795 152.315C56.9795 152.315 56.9476 152.315 56.934 152.305C56.5337 152.079 55.765 151.207 55.8469 150.764C55.8605 150.684 55.9197 150.543 56.138 150.514C56.279 150.495 56.4109 150.538 56.5246 150.637C56.9704 151.014 57.0659 152.169 57.0659 152.216C57.0659 152.249 57.0522 152.282 57.0249 152.301C57.0113 152.31 56.9931 152.315 56.9749 152.315H56.9795ZM56.2017 150.698C56.2017 150.698 56.1744 150.698 56.1607 150.698C56.0425 150.712 56.0334 150.769 56.0288 150.792C55.9788 151.056 56.47 151.716 56.8657 152.027C56.8203 151.693 56.6975 151.019 56.4109 150.778C56.3472 150.722 56.2744 150.693 56.2017 150.693V150.698Z" fill="#407BFF"/>
<path d="M25.5306 150.755C25.5306 150.755 25.5215 150.755 25.5124 150.755C24.8802 150.708 23.7794 150.557 23.4701 150.066C23.3792 149.92 23.361 149.755 23.4247 149.576C23.4611 149.473 23.5338 149.402 23.6339 149.374C24.1479 149.246 25.4351 150.453 25.5807 150.59C25.608 150.618 25.6171 150.66 25.6034 150.698C25.5898 150.731 25.5625 150.75 25.5306 150.755ZM23.7021 149.553C23.7021 149.553 23.6839 149.553 23.6748 149.553C23.6339 149.562 23.6112 149.586 23.593 149.633C23.552 149.755 23.5611 149.859 23.6203 149.958C23.7931 150.231 24.3935 150.444 25.2486 150.538C24.7301 150.076 23.9978 149.515 23.6976 149.548L23.7021 149.553Z" fill="#407BFF"/>
<path d="M25.4579 150.726C25.4579 150.726 25.4488 150.717 25.4488 150.712C25.1031 150.165 24.5436 149.166 24.7347 148.615C24.7893 148.45 24.9075 148.337 25.0804 148.28C25.185 148.247 25.2805 148.261 25.3624 148.332C25.7717 148.681 25.6353 150.472 25.6171 150.675C25.6171 150.712 25.5853 150.75 25.5489 150.759C25.517 150.769 25.4852 150.759 25.4624 150.731L25.4579 150.726ZM25.2669 148.492C25.2669 148.492 25.2532 148.478 25.2487 148.473C25.2168 148.445 25.1804 148.44 25.1349 148.454C25.0167 148.492 24.9439 148.563 24.903 148.676C24.7984 148.987 25.003 149.609 25.4533 150.368C25.4943 149.661 25.4715 148.718 25.2669 148.492Z" fill="#407BFF"/>
<path d="M63.3201 29.513C64.2071 30.8092 64.9621 32.0631 65.7308 33.3688C66.4995 34.6604 67.2091 35.9943 67.9005 37.3472C69.256 40.067 70.5023 42.8717 71.3756 46.0063C71.4802 46.4022 71.5803 46.7982 71.6712 47.2083C71.7167 47.411 71.7622 47.6184 71.7986 47.8258L71.8577 48.1369L71.8896 48.2972L71.926 48.5517C72.0761 49.881 71.8714 50.8567 71.6485 51.7429C71.1754 53.5011 70.4886 54.9294 69.7517 56.3105C69.0103 57.6822 68.2007 58.969 67.3365 60.204C66.4722 61.4437 65.5762 62.6175 64.5755 63.7723L62.2102 62.0518C63.4429 59.4923 64.6983 56.8667 65.6626 54.293C65.9037 53.652 66.122 53.0109 66.3039 52.384C66.495 51.7617 66.6451 51.149 66.7224 50.5927C66.8043 50.0507 66.7952 49.5416 66.7361 49.4049C66.7361 49.4002 66.7315 49.3907 66.727 49.386L66.6997 49.2776L66.6405 49.0514C66.6041 48.9005 66.5632 48.7497 66.5132 48.5988C66.4268 48.2972 66.3221 47.9861 66.2175 47.6797C65.3578 45.1955 64.1161 42.6737 62.7879 40.2131C62.1238 38.9734 61.4142 37.7573 60.7092 36.5317C60.0042 35.3203 59.2355 34.09 58.5214 32.9493L63.3201 29.513Z" fill="#FFB573"/>
<path d="M62.747 27.2174C66.354 27.9716 69.5198 37.1162 69.5198 37.1162L61.992 43.4703C61.992 43.4703 59.5266 38.8226 57.5526 34.3398C55.4011 29.4564 58.3804 26.3076 62.7516 27.2174H62.747Z" fill="white"/>
<path opacity="0.4" d="M62.747 27.2174C66.354 27.9716 69.5198 37.1162 69.5198 37.1162L61.992 43.4703C61.992 43.4703 59.5266 38.8226 57.5526 34.3398C55.4011 29.4564 58.3804 26.3076 62.7516 27.2174H62.747Z" fill="#407BFF"/>
<path d="M12.3952 40.1631L10.5768 46.9584L11.0107 47.0831L12.8292 40.2878L12.3952 40.1631Z" fill="#407BFF"/>
<path d="M9.91085 49.4681L9.12439 52.407L9.55832 52.5317L10.3448 49.5928L9.91085 49.4681Z" fill="#407BFF"/>
<path d="M61.188 37.0039L23.3755 26.1516C20.5018 25.3268 17.5271 27.0724 16.7312 30.0504L6.25908 69.236C5.46321 72.214 7.14762 75.2968 10.0213 76.1215L47.8338 86.9739C50.7075 87.7987 53.6823 86.0531 54.4781 83.0751L64.9503 43.8895C65.7461 40.9115 64.0617 37.8287 61.188 37.0039Z" fill="#407BFF"/>
<path d="M38.6214 47.6184C38.4213 47.6184 38.2211 47.5901 38.021 47.5335C36.8247 47.1894 36.1197 45.9073 36.4518 44.6629L38.2666 37.8751C38.5987 36.6354 39.8404 35.9048 41.0367 36.2489C42.233 36.593 42.938 37.8751 42.606 39.1195L40.7911 45.9073C40.5136 46.9396 39.6085 47.6184 38.626 47.6184H38.6214Z" fill="white"/>
<path d="M30.7797 76.028C30.6615 76.028 30.5387 76.0091 30.4204 75.9761C29.7017 75.7687 29.2787 75.0004 29.4789 74.2556L31.2937 67.4679C31.4939 66.7231 32.2353 66.2894 32.954 66.4921C33.6726 66.6995 34.0956 67.4679 33.8955 68.2126L32.0806 75.0004C31.9169 75.6179 31.3711 76.028 30.7797 76.028Z" fill="white"/>
<path d="M45.4308 51.4978C45.1942 51.4978 44.9668 51.3705 44.844 51.1443C44.6621 50.8096 44.7758 50.3806 45.0987 50.1921L51.0164 46.7181C51.3393 46.5295 51.7533 46.6474 51.9352 46.982C52.1171 47.3167 52.0034 47.7457 51.6805 47.9342L45.7628 51.4082C45.6582 51.4695 45.5445 51.4978 45.4308 51.4978Z" fill="white"/>
<path d="M19.8678 67.4302C19.3175 67.4302 18.7853 67.1332 18.4942 66.6005C18.0666 65.8181 18.3304 64.8188 19.09 64.3757L25.0077 60.9017C25.7628 60.4586 26.7271 60.732 27.1546 61.5192C27.5822 62.3016 27.3184 63.3009 26.5588 63.744L20.6411 67.218C20.3955 67.3642 20.1317 67.4302 19.8678 67.4302Z" fill="white"/>
<path d="M53.0404 62.4996C52.9631 62.4996 52.8812 62.4902 52.7993 62.4666L46.2494 60.5858C45.7718 60.4491 45.4898 59.9353 45.6217 59.4404C45.7536 58.9455 46.2494 58.6532 46.727 58.7899L53.2769 60.6707C53.7545 60.8074 54.0365 61.3212 53.9046 61.8161C53.7955 62.2309 53.4316 62.4996 53.0359 62.4996H53.0404Z" fill="white"/>
<path d="M24.7257 55.3065C24.5665 55.3065 24.4073 55.2829 24.2435 55.2405L17.6936 53.3597C16.7338 53.0863 16.1744 52.0587 16.4382 51.0641C16.702 50.0695 17.6936 49.4897 18.6533 49.7631L25.2033 51.6439C26.163 51.9173 26.7225 52.9449 26.4587 53.9395C26.2358 54.7644 25.5126 55.3065 24.7257 55.3065Z" fill="white"/>
<path d="M44.5211 74.0388C44.1299 74.0388 43.7478 73.8267 43.5431 73.4496L40.1908 67.317C39.8861 66.7561 40.0771 66.0443 40.6139 65.7285C41.1551 65.4127 41.842 65.6107 42.1467 66.1669L45.499 72.2994C45.8038 72.8604 45.6127 73.5721 45.076 73.888C44.8986 73.9917 44.7121 74.0388 44.5211 74.0388Z" fill="white"/>
<path d="M30.0475 48.481C29.3425 48.481 28.6556 48.0992 28.2827 47.4157L24.9304 41.2831C24.38 40.2744 24.7211 38.9923 25.6945 38.4219C26.6679 37.8515 27.9051 38.2051 28.4555 39.2138L31.8078 45.3464C32.3582 46.3551 32.017 47.6372 31.0436 48.2076C30.7298 48.3914 30.3841 48.481 30.0475 48.481Z" fill="white"/>
<path d="M63.5748 61.1373L59.6721 60.9912L61.5643 65.6955C61.5643 65.6955 64.9166 65.0544 64.7847 63.1737L63.5793 61.1326L63.5748 61.1373Z" fill="#FFB573"/>
<path d="M57.0568 62.9333L57.9938 66.5298L61.5598 65.6955L59.6676 60.9912L57.0568 62.9333Z" fill="#FFB573"/>
</g>
<defs>
<clipPath id="clip0_1_1028">
<rect width="80" height="157" fill="white" transform="translate(0.5 0.5)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -30,19 +30,20 @@ h5 {
--black-pale: #1b1a17;
--red: #f70000;
--red-pale: #ff726f;
--grey: #e6e6e6;
--grey: #f5f5f5;
--grey-pale: #cfd2cf;
--grey-semi-dark: #808080;
--grey-dark: #54595e;
--blue: #4945ff;
--blue-dark: #051f61;
--grey-dark: #3e3e3e;
--blue: #2954e9;
--blue-dark: #0a1f69;
--blue-geovisio: #34495e;
--blue-semi: rgba(207, 226, 255, 0.5);
--blue-pale: #f9fafd;
--blue-semi: #d7dffc;
--blue-pale: #f2f5ff;
--beige: #f5f3ec;
--yellow: #fec868;
--orange: #ff6f00;
--green: #59ce8f;
--orange-pale: #fffafa;
--green: #7ec636;
--green-pale: #f0ffee;
}
@@ -52,13 +53,3 @@ h5 {
place-items: center;
}
}
@media (max-width: toRem(50)) {
@supports (-webkit-touch-callout: none) {
/* CSS specific to iOS devices */
body {
min-height: -webkit-fill-available;
min-height: moz-available;
min-height: fill-available;
}
}
}

View File

@@ -1,44 +0,0 @@
<template>
<p class="instance-beta">
{{ title($t('general.header.title')) }}
<span class="beta">{{ $t('general.header.beta_text') }}</span>
</p>
</template>
<script lang="ts" setup>
import { title } from '@/utils/index'
</script>
<style lang="scss" scoped>
.beta {
@include text(xs-r-regular);
color: var(--red);
border: toRem(0.1) solid var(--red);
border-radius: toRem(0.5);
padding: toRem(0.2) toRem(0.3);
margin-left: toRem(0.5);
position: absolute;
top: toRem(-1);
right: toRem(-9.5);
width: toRem(9);
display: flex;
justify-content: center;
}
@media (max-width: toRem(76.8)) {
.instance-beta {
display: flex;
align-items: center;
justify-content: center;
background-color: var(--grey);
padding: toRem(1);
margin-bottom: 0;
}
.beta {
position: relative;
top: initial;
right: initial;
margin-left: toRem(1);
}
}
</style>

View File

@@ -45,7 +45,7 @@ defineProps({
background-color: transparent;
position: relative;
z-index: 1;
border-radius: toRem(0.5);
border-radius: toRem(1);
padding: toRem(1.3) toRem(2) toRem(1.3);
.icon {
font-size: toRem(2);
@@ -75,7 +75,7 @@ defineProps({
}
.button--red {
color: var(--red);
background-color: var(--white);
background-color: transparent;
border: toRem(0.1) solid var(--red);
.icon {
margin-right: 0;
@@ -87,12 +87,11 @@ defineProps({
}
}
.button--white {
color: var(--black);
background-color: var(--white);
border: toRem(0.1) solid var(--black);
color: var(--blue);
border: toRem(0.1) solid var(--blue);
.icon {
font-size: toRem(1.4);
color: var(--black);
color: var(--blue);
margin-right: 0;
}
.text {
@@ -109,6 +108,9 @@ defineProps({
margin-right: 0;
}
}
.background-white {
background-color: var(--white);
}
.link--grey {
color: var(--grey-semi-dark);
.icon {

View File

@@ -1,99 +1,46 @@
<template>
<footer class="footer">
<div class="wrapper-footer">
<div class="wrapper-section">
<h3 class="title">{{ $t('general.footer.panoramax_title') }}</h3>
<ul class="link-list">
<li class="link">
<Link
:text="$t('general.footer.panoramax_site')"
type="external"
path-external="https://panoramax.fr/"
look="link"
/>
</li>
<li class="link">
<Link
:text="$t('general.footer.panoramax_faq')"
type="external"
path-external="https://panoramax.fr/foire-aux-questions"
look="link"
/>
</li>
</ul>
</div>
<div class="wrapper-section">
<h3 class="title">{{ $t('general.footer.information_title') }}</h3>
<ul class="link-list">
<li class="link">
<Link
:text="$t('general.footer.information_forum')"
type="external"
path-external="https://forum.geocommuns.fr/c/panoramax/6"
look="link"
/>
</li>
<li class="link">
<Link
:text="$t('general.footer.information_gitlab')"
type="external"
path-external="https://gitlab.com/geovisio"
look="link"
/>
</li>
<li class="link">
<Link
:text="$t('general.footer.information_github')"
type="external"
path-external="https://github.com/panoramax-project/"
look="link"
/>
</li>
</ul>
</div>
<div class="wrapper-section">
<h3 class="title">{{ $t('general.footer.rs_title') }}</h3>
<ul class="logo-list">
<li class="logo">
<Link
:image="{
url: 'mastodon.svg',
alt: $t('general.footer.mastodon_alt')
}"
type="external"
path-external="https://mapstodon.space/@panoramax"
/>
</li>
<li class="logo">
<Link
:image="{
url: 'linkedin.svg',
alt: $t('general.footer.linkedin_alt')
}"
type="external"
path-external="https://github.com/panoramax-project/"
/>
</li>
<li>
<Link
:image="{
url: 'x.svg',
alt: $t('general.footer.twitter_alt')
}"
type="external"
path-external="https://twitter.com/panoramax_"
/>
</li>
</ul>
</div>
</div>
<div class="ay11-text">
<Link
:text="$t('general.footer.ay11_text')"
:route="{ name: 'ay11' }"
look="link"
/>
</div>
<ul class="link-list">
<li class="link-item">
<div class="link">
<Link
:text="$t('general.footer.panoramax_site')"
type="external"
target="_blank"
path-external="https://panoramax.fr/"
look="link"
:image="{
url: 'logo.jpeg',
alt: $t('general.footer.gitlab_logo')
}"
/>
</div>
</li>
<li class="link-item">
<div class="link">
<Link
:text="$t('general.footer.information_gitlab')"
type="external"
target="_blank"
path-external="https://gitlab.com/geovisio"
look="link"
:image="{
url: 'gitlab-logo.svg',
alt: $t('general.footer.gitlab_logo')
}"
/>
</div>
</li>
<li class="link-item">
<div class="link">
<Link
:text="$t('general.footer.ay11_text')"
:route="{ name: 'ay11' }"
look="link link--grey"
/>
</div>
</li>
</ul>
</footer>
</template>
@@ -107,54 +54,44 @@ ul {
margin: 0;
}
.footer {
padding: toRem(2);
padding: toRem(1.5) toRem(3);
border-top: toRem(0.1) solid var(--grey);
}
.wrapper-footer {
display: flex;
}
.wrapper-section {
width: 33%;
display: flex;
flex-direction: column;
}
.title {
@include text(m-regular);
color: var(--blue);
margin-bottom: toRem(1.5);
}
.link-list {
display: flex;
flex-direction: column;
align-items: initial;
width: 100%;
}
.logo-list {
display: flex;
align-items: center;
}
.link-item {
width: 100%;
&:last-child {
font-style: italic;
text-align: end;
.link {
width: 100%;
}
}
}
.link {
margin-bottom: toRem(0.3);
color: var(--blue-dark);
@include text(s-regular);
height: toRem(2);
width: fit-content;
}
.logo {
margin-right: toRem(2);
height: toRem(3);
}
.ay11-text {
display: flex;
justify-content: center;
width: 100%;
height: toRem(2);
}
@media (max-width: toRem(50)) {
.title {
margin-bottom: 0;
}
.footer {
padding: toRem(2);
}
.wrapper-footer {
flex-direction: column;
}
.ay11-text {
margin-top: toRem(2);
justify-content: initial;
}
}
</style>

View File

@@ -1,15 +1,18 @@
<template>
<header class="header">
<div class="responsive beta">
<beta-text />
<div class="responsive entry-instance">
<InstanceName />
</div>
<nav class="nav">
<div class="wrapper-logo desktop">
<Link
:image="{ url: 'logo.jpeg', alt: $t('general.header.alt_logo') }"
:text="title($t('general.header.title'))"
:route="{ name: 'home' }"
/>
>
<template v-slot:content>
<InstanceName />
</template>
</Link>
</div>
<div class="wrapper-logo responsive">
<Link
@@ -21,80 +24,79 @@
/>
</div>
<div ref="list" class="wrapper-entries">
<ul
<HeaderOpen
v-if="isLogged && authEnabled"
:class="['nav-list', { 'menu-open': !menuIsClosed }]"
>
<li class="logged-link">
<Link
:text="$t('general.header.sequences_text')"
icon="bi bi-images"
:route="{ name: 'my-sequences' }"
@click.native="closeModal"
/>
</li>
<li v-if="userProfileUrl.length" class="logged-link">
<Link
:route="{ name: 'my-information' }"
icon="bi bi-person"
:text="$t('general.header.my_information_text')"
@click.native="closeModal"
/>
</li>
<li class="logged-link">
<Link
:route="{ name: 'my-settings' }"
icon="bi bi-gear"
:text="$t('general.header.my_settings_text')"
@click.native="closeModal"
/>
</li>
<li class="logged-link">
<Link
type="external"
icon="bi bi-power"
:text="$t('general.header.logout_text')"
:path-external="getAuthRoute('auth/logout', route.path)"
@click.native="closeModal"
/>
</li>
</ul>
:menu-is-closed="menuIsClosed"
:user-profile-url-length="userProfileUrl.length"
@triggerClose="closeModal"
/>
<div class="wrapper-right-entries">
<div v-if="isLogged && authEnabled">
<div>
<Link
v-if="isLogged"
:text="$t('general.header.sequences_text')"
:route="{ name: 'my-sequences' }"
look="link--blue"
class="desktop"
@click.native="closeModal"
/>
<Link
v-else
:text="$t('general.header.contribute_text')"
:route="{ name: 'why-contribute' }"
look="link--blue"
@click.native="closeModal"
/>
</div>
<div v-if="isLogged && authEnabled" class="link-upload">
<Link
:text="$t('general.header.upload_text')"
look="button button--blue"
:route="{ name: 'upload-pictures' }"
class="desktop"
@click.native="closeModal"
/>
</div>
<div>
<Link
:text="$t('general.header.contribute_text')"
:route="{ name: 'share-pictures' }"
data-test="link-logged-upload"
look="button button--blue"
icon="bi bi-plus-lg"
:route="{ name: 'upload-pictures' }"
class="responsive"
@click.native="closeModal"
/>
</div>
<button
<AccountButton
v-if="isLogged && authEnabled"
class="menu-burger"
:aria-label="ariaLabel"
@click="toggleMenu"
>
<div v-if="isLogged" class="item-with-sub">
<span>{{ userName }}</span>
</div>
<div v-else>
<i v-if="!menuIsClosed" class="cross bi bi-x-lg"></i>
<i v-else class="bi bi-list"></i>
</div>
</button>
:is-logged="isLogged"
:user-name="userName"
:menu-is-closed="menuIsClosed"
@triggerToggleMenu="toggleMenu"
/>
<div v-else-if="!isLogged && authEnabled">
<Link
type="external"
icon="bi bi-person-circle"
:path-external="getAuthRoute('auth/login', route.path)"
/>
<div class="desktop" data-test="button-login-desktop">
<Link
type="external"
:path-external="getAuthRoute('auth/login', route.path)"
>
<template v-slot:content>
<span class="login-text">{{
$t('general.header.login_text')
}}</span>
<span class="register-text">{{
$t('general.header.register_text')
}}</span>
</template>
</Link>
</div>
<div class="responsive" data-test="button-login-responsive">
<Link
type="external"
icon="bi bi-person-circle"
look="link--blue-dark"
:path-external="getAuthRoute('auth/login', route.path)"
/>
</div>
</div>
</div>
</div>
@@ -109,9 +111,10 @@ import { useCookies } from 'vue3-cookies'
import { useRoute } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { getAuthRoute } from '@/utils/auth'
import { title } from '@/utils/index'
import Link from '@/components/Link.vue'
import BetaText from '@/components/BetaText.vue'
import InstanceName from '@/components/InstanceName.vue'
import HeaderOpen from '@/components/header/HeaderOpen.vue'
import AccountButton from '@/components/header/AccountButton.vue'
const { cookies } = useCookies()
const { t } = useI18n()
@@ -151,15 +154,16 @@ const userName = computed((): string =>
.header {
display: flex;
align-items: center;
height: toRem(8);
background-color: var(--blue-pale);
min-height: toRem(8);
background-color: var(--white);
border-bottom: toRem(0.1) solid var(--grey-pale);
}
.nav {
width: 100%;
padding-right: toRem(2);
padding-left: toRem(2);
display: flex;
justify-content: space-between;
align-items: center;
padding: toRem(1.5) toRem(3);
}
.wrapper-logo {
display: flex;
@@ -173,114 +177,51 @@ const userName = computed((): string =>
display: none;
}
.desktop {
display: block;
}
.wrapper-logo p {
@include text(m-r-regular);
margin-bottom: 0;
margin-left: toRem(1);
position: relative;
}
.item-with-sub {
position: relative;
display: flex;
align-items: center;
}
.item-with-sub:hover .sub-nav-block {
display: block;
}
.sub-nav-block {
display: none;
border-radius: toRem(0.5);
border: toRem(0.1) solid var(--black);
background-color: var(--white);
position: absolute;
right: 0;
top: toRem(3.5);
z-index: 1;
width: toRem(15);
}
.logged-link {
display: flex;
padding: toRem(0.5) toRem(2) toRem(0.7);
}
.logged-link:hover {
border-radius: toRem(0.5);
background-color: var(--grey);
}
.nav-list-item {
margin-right: toRem(1.5);
}
.wrapper-right-entries {
display: flex;
align-items: center;
div {
div:first-child {
margin-right: toRem(2);
}
}
.cross {
font-size: toRem(2);
}
.item-with-sub {
margin-right: toRem(1.5);
}
.nav {
align-items: center;
padding: toRem(1.5);
}
.nav-list {
display: none;
flex-direction: column;
justify-content: center;
align-items: initial;
position: absolute;
width: toRem(20);
top: toRem(8);
right: 0;
z-index: 2;
background-color: var(--white);
box-shadow: 0 toRem(0.2) toRem(0.4) rgb(0 0 0 / 10%);
padding-left: 0;
padding-top: toRem(1);
padding-bottom: toRem(1);
border-radius: toRem(1);
}
.menu-burger {
display: block;
background-color: transparent;
border: none;
width: toRem(2.5);
font-size: toRem(2.5);
padding: 0;
.item-with-sub {
@include text(s-regular);
display: flex;
justify-content: center;
align-items: center;
background-color: var(--blue);
color: var(--white);
height: toRem(3);
width: toRem(3);
border-radius: 50%;
margin-right: 0;
div:last-child {
.desktop {
margin-right: 0;
}
}
}
.menu-open {
display: flex;
.link-upload {
margin-right: toRem(2);
}
@media (max-width: toRem(50)) {
.login-text {
color: var(--blue-dark);
border-right: toRem(0.1) solid var(--blue-dark);
padding-right: toRem(0.5);
}
.register-text {
padding-left: toRem(0.5);
color: var(--blue);
}
@media (max-width: toRem(76.8)) {
.nav {
padding-right: toRem(2);
padding-left: toRem(2);
}
.header {
flex-direction: column;
height: toRem(11);
min-height: toRem(10);
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 4;
}
.nav-list {
top: toRem(11);
.entry-instance {
background-color: var(--blue-pale);
width: 100%;
display: flex;
justify-content: center;
}
.desktop {
display: none;
@@ -288,11 +229,5 @@ const userName = computed((): string =>
.responsive {
display: flex;
}
.beta {
width: 100%;
.instance-beta {
width: 100%;
}
}
}
</style>

View File

@@ -0,0 +1,83 @@
<template>
<div :class="['information-block', look]">
<div class="wrapper-cross">
<slot name="cross"></slot>
</div>
<div>
<div class="icon-block">
<img
src="@/assets/images/icon/info-blue.svg"
alt=""
class="icon-block-img"
/>
<h3 v-if="title" class="subtitle">
{{ title }}
</h3>
</div>
<p v-if="text" class="information-text">
{{ text }}
</p>
</div>
<slot name="button"></slot>
</div>
</template>
<script setup lang="ts">
defineProps({
text: { type: String, default: null },
title: { type: String, default: null },
look: { type: String, default: '' }
})
</script>
<style scoped lang="scss">
h3 {
padding: 0;
margin: 0;
}
.information-block {
position: relative;
border-left: toRem(1.4) solid var(--blue);
padding: toRem(2) toRem(2) toRem(1.5);
background-color: var(--white);
border-radius: toRem(1.5);
display: flex;
align-items: flex-end;
justify-content: space-between;
flex-wrap: wrap;
}
.wrapper-cross {
position: absolute;
top: toRem(1);
right: toRem(1);
}
.blue {
background-color: var(--blue-pale);
}
.icon-block {
display: flex;
align-items: center;
margin-bottom: toRem(0.5);
}
.icon-block-img {
margin-right: toRem(0.5);
height: toRem(2.2);
}
.subtitle {
@include text(h2);
color: var(--blue-dark);
}
.information-text {
margin-top: toRem(1);
@include text(m-r-regular);
}
@media (max-width: toRem(50)) {
.information-block {
border-left: toRem(1) solid var(--blue);
}
.icon-block {
flex-direction: column;
align-items: flex-start;
}
}
</style>

View File

@@ -74,9 +74,6 @@ function checkPicturesType(files: FileList): number {
<style scoped lang="scss">
.file-upload {
border: toRem(0.1) dashed var(--blue);
background-color: var(--blue-semi);
border-radius: toRem(0.5);
padding: toRem(0.3) toRem(0.3) toRem(3);
display: flex;
flex-direction: column;
@@ -102,16 +99,17 @@ function checkPicturesType(files: FileList): number {
}
.input-text {
font-size: toRem(2);
@include text(m-regular);
font-weight: bold;
@include text(m-r-regular);
width: toRem(21);
text-align: center;
margin-bottom: toRem(1);
font-weight: 590;
}
.input-text-type {
@include text(xs-r-regular);
}
.last-word {
color: var(--blue);
text-decoration: underline;
}
</style>

View File

@@ -0,0 +1,49 @@
<template>
<div class="wrapper-instance">
<span class="panoramax-text">{{ $t('general.header.title') }}</span>
<span v-if="instanceName" class="instance-text">{{ instanceName }}</span>
<span class="beta-version">{{ $t('general.header.beta_text') }}</span>
</div>
</template>
<script lang="ts" setup>
import { computed } from 'vue'
const instanceName = computed((): string | null => {
const instanceName = import.meta.env.VITE_INSTANCE_NAME
if (instanceName) return instanceName
return null
})
</script>
<style lang="scss" scoped>
.wrapper-instance {
padding: toRem(1) toRem(1) toRem(1) 0;
position: relative;
}
.panoramax-text,
.instance-text {
@include text(h2);
}
.panoramax-text {
font-weight: bolder;
margin-right: toRem(0.7);
}
.instance-text {
padding-left: toRem(0.7);
border-left: toRem(0.1) solid var(--blue-dark);
font-weight: normal;
}
.beta-version {
border: toRem(0.1) solid var(--blue);
color: var(--blue);
padding: toRem(0.2) toRem(0.5);
@include text(xss-regular);
border-radius: toRem(0.5);
background-color: var(--white);
position: absolute;
top: toRem(0.3);
margin-left: toRem(0.5);
width: toRem(7);
text-align: center;
}
</style>

View File

@@ -0,0 +1,36 @@
<template>
<div class="icon-block">
<slot></slot>
<p class="license-text">
{{
$t('pages.share_pictures.information_text2', {
word: 'la license'
})
}}
</p>
<Link
:href="url"
:text="text"
target="_blank"
type="external"
look="link--grey"
/>
</div>
</template>
<script setup lang="ts">
import Link from '@/components/Link.vue'
defineProps({
url: { type: String, default: null },
text: { type: String, default: null }
})
</script>
<style scoped lang="scss">
.icon-block {
display: flex;
}
.license-text {
margin-right: toRem(0.5);
}
</style>

View File

@@ -6,11 +6,12 @@
:class="['default', look, { disabled }]"
:title="titleImg"
v-bind="$attrs"
@click="$emit('trigger')"
@click="triggerButton"
>
<i v-if="icon" :class="[icon, 'icon']"></i>
<img v-if="image" :src="img(image.url)" :alt="image.alt" class="logo" />
<span v-if="text" class="text">{{ text }}</span>
<slot name="content"></slot>
</a>
<router-link
v-else
@@ -22,12 +23,14 @@
<i v-if="icon" :class="[icon, 'icon']"></i>
<img v-if="image" :src="img(image.url)" :alt="image.alt" class="logo" />
<span v-if="text" class="text">{{ text }}</span>
<slot name="content"></slot>
</router-link>
</template>
<script lang="ts" setup>
import { useI18n } from 'vue-i18n'
import { computed } from 'vue'
const emit = defineEmits<{ (e: 'trigger'): void }>()
import type { PropType } from 'vue'
import type { RouteLocationRaw } from 'vue-router'
import { img } from '../utils/image'
@@ -54,38 +57,53 @@ const props = defineProps({
const titleImg = computed<string>(() =>
props.disabled ? t('general.header.contribute_text') : ''
)
function triggerButton() {
if (props.disabled) return
emit('trigger')
}
</script>
<style lang="scss" scoped>
.default {
@include text(s-regular);
@include text(m-r-regular);
display: flex;
align-items: center;
justify-content: center;
color: var(--black);
text-decoration: none;
height: inherit;
width: inherit;
.icon {
margin-right: toRem(1);
}
&:hover {
opacity: toRem(0.8);
opacity: 0.8;
}
}
.icon {
color: var(--black);
font-size: toRem(2.4);
margin-right: toRem(1);
}
.logo {
height: inherit;
border-radius: toRem(0.5);
margin-right: toRem(1);
height: inherit;
}
.button {
height: toRem(4);
border-radius: toRem(0.5);
padding: toRem(1.3) toRem(2) toRem(1.3);
border-radius: toRem(1);
padding: toRem(1.5);
background-color: var(--black);
color: var(--white);
text-align: center;
.icon {
margin-right: 0;
}
&.disabled {
background-color: var(--grey);
opacity: 0.5;
}
}
.text {
width: 100%;
@@ -99,6 +117,18 @@ const titleImg = computed<string>(() =>
color: var(--grey-semi-dark);
text-decoration: underline;
}
.link--blue-dark {
color: var(--blue-dark);
.icon {
color: var(--blue-dark);
}
}
.link--blue {
color: var(--blue);
.icon {
color: var(--blue);
}
}
.button--white {
background-color: var(--white);
color: var(--black);
@@ -110,13 +140,14 @@ const titleImg = computed<string>(() =>
background-color: var(--black);
color: var(--white);
.icon {
color: white;
color: var(--white);
}
}
}
.button--white-blue {
background-color: var(--white);
border: toRem(0.1) solid var(--blue);
color: var(--blue);
.icon {
font-size: toRem(1.4);
color: var(--blue);
@@ -130,6 +161,10 @@ const titleImg = computed<string>(() =>
color: var(--white);
}
}
.button--blue-bleu {
background-color: var(--blue-semi);
color: var(--blue);
}
.disabled {
color: grey;
cursor: not-allowed;
@@ -153,7 +188,6 @@ const titleImg = computed<string>(() =>
.icon {
color: var(--white);
font-size: toRem(2.8);
margin-right: 0;
}
}
.no-text {
@@ -165,6 +199,10 @@ const titleImg = computed<string>(() =>
}
}
@media (max-width: toRem(50)) {
.default {
min-height: toRem(4);
min-width: toRem(4);
}
.icon {
margin-right: toRem(0.5);
}

99
src/components/Modal.vue Normal file
View File

@@ -0,0 +1,99 @@
<template>
<div
class="modal fade"
id="bs-modal"
tabindex="-1"
role="dialog"
aria-labelledby="exampleModalCenterTitle"
aria-hidden="true"
>
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<button class="close-button" type="button" @click="bsModal.hide()">
<i class="bi bi-x-circle-fill"></i>
</button>
<div class="modal-header">
<h5>{{ $t('pages.upload.modal_error_title') }}</h5>
</div>
<div class="modal-body">
<ul>
<li v-for="item in uploadErrors" class="error-item">
<span>{{ item.name }} - </span>
<span>{{ item.message }}</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import type { PropType } from 'vue'
import { Modal } from 'bootstrap'
let bsModal = ref()
import type { uploadErrorInterface } from '@/views/interfaces/UploadPicturesView'
defineProps({
uploadErrors: {
type: Array as PropType<uploadErrorInterface[]>,
default: []
}
})
onMounted(() => {
bsModal.value = new Modal(document.getElementById('bs-modal'), {})
})
function displayModal() {
bsModal.value.show()
}
function closeModal() {
bsModal.value.hide()
}
defineExpose({ show: displayModal, close: closeModal })
</script>
<style scoped lang="scss">
ul {
padding: 0;
}
.modal {
background: rgba(10, 31, 105, 0.6);
}
.error-item {
padding: toRem(1);
&:nth-child(odd) {
background-color: var(--grey);
}
}
.modal-content {
border-radius: toRem(1.5);
}
.modal-body {
overflow-y: auto;
color: var(--grey-semi-dark);
}
.modal-header {
color: var(--blue-dark);
}
.close-button {
font-size: toRem(3);
width: fit-content;
border-radius: 50%;
border: none;
background: transparent;
position: absolute;
right: toRem(-4);
top: toRem(-4);
color: var(--white);
}
@media (max-width: toRem(50)) {
.close-button {
right: toRem(0);
top: toRem(-5);
}
}
</style>

126
src/components/Viewer.vue Normal file
View File

@@ -0,0 +1,126 @@
<template>
<div id="viewer" class="entry-viewer"></div>
</template>
<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'
import type { ViewerInterface } from '@/views/interfaces/common'
import { getIgnTiles } from '@/utils/mapAndViewer'
import { Viewer, StandaloneMap } from 'geovisio'
import { createUrlLink } from '@/utils'
import { createLink } from '@/components-viewer/reportLink'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
let mapIsLoaded = ref<boolean>(false)
let viewer = ref()
const props = defineProps({
fetchOptions: { type: Object, default: {} },
geovisioViewer: { type: Boolean, default: true },
bbox: { type: Array, default: null }
})
defineExpose({
viewer
})
onMounted(async () => {
const tiles = import.meta.env.VITE_TILES
const maxZoom = import.meta.env.VITE_MAX_ZOOM
const zoom = import.meta.env.VITE_ZOOM
const center = import.meta.env.VITE_CENTER
let paramsViewer: ViewerInterface
try {
if (props.geovisioViewer) {
paramsViewer = { map: { startWide: true } }
if (center && center !== '') {
const centerMap = center.split(',').map((el: string) => parseInt(el))
paramsViewer = {
map: {
...paramsViewer.map,
center: centerMap
}
}
}
if (zoom && zoom !== '') {
paramsViewer = {
map: {
...paramsViewer.map,
zoom: parseFloat(zoom)
}
}
}
if (maxZoom && maxZoom !== '') {
paramsViewer = {
map: {
...paramsViewer.map,
maxZoom: parseInt(maxZoom)
}
}
}
if (tiles) {
const style = tiles.includes('wxs.ign.fr') ? await getIgnTiles() : tiles
paramsViewer = {
map: {
...paramsViewer.map,
style
}
}
}
if (props.fetchOptions) {
paramsViewer = {
...paramsViewer,
...props.fetchOptions
}
}
const reportLink = document.createElement('div')
reportLink.className = 'gvs-group gvs-group-large gvs-group-btnpanel'
viewer.value = await new Viewer(
'viewer', // Div ID
`${import.meta.env.VITE_API_URL}/api/search`,
{
...paramsViewer,
widgets: { customWidget: reportLink }
}
)
if (viewer.value && viewer.value.addEventListener) {
viewer.value.addEventListener(
'picture-loaded',
async (e: { detail: { picId: string } }): Promise<void> => {
const href = t('pages.home.report_mail', {
picId: e.detail.picId,
link: createUrlLink(e.detail.picId)
})
reportLink.innerHTML = createLink(
href,
t('pages.home.report_button_text')
)
}
)
}
} else {
viewer.value = await new StandaloneMap(
'viewer', // Div ID
`${import.meta.env.VITE_API_URL}/api/search`
)
}
mapIsLoaded.value = true
} catch (err) {
console.log(err)
}
})
onUnmounted(() => {
if (viewer.value && props.geovisioViewer) viewer.value.destroy()
})
</script>
<style scoped lang="scss">
.entry-viewer {
font-size: initial;
position: relative;
width: 100%;
height: 100%;
}
.gvs-focus-map .entry-report-button {
display: none;
}
</style>

View File

@@ -0,0 +1,70 @@
<template>
<button
class="menu-burger"
:aria-label="ariaLabel"
@click="$emit('triggerToggleMenu')"
>
<div v-if="isLogged" class="wrapper-name">
<div class="item-with-sub">
<span>{{ userName }}</span>
</div>
<span class="desktop">{{ $t('general.header.my_account') }}</span>
<img
src="@/assets/images/icon/arrow-down.svg"
alt=""
:class="['arrow-img', { 'arrow-up': !menuIsClosed }]"
/>
</div>
</button>
</template>
<script setup lang="ts">
defineProps({
menuIsClosed: { type: Boolean, default: true },
isLogged: { type: Boolean, default: false },
userName: { type: String, default: null },
ariaLabel: { type: String, default: null }
})
</script>
<style scoped lang="scss">
.menu-burger {
display: block;
background-color: transparent;
border: none;
font-size: toRem(2.5);
padding: 0;
color: var(--blue-dark);
}
.wrapper-name {
display: flex;
align-items: center;
@include text(m-r-regular);
}
.arrow-img {
margin-left: toRem(0.5);
}
.arrow-up {
transform: rotate(180deg);
}
.item-with-sub {
@include text(s-regular);
display: flex;
justify-content: center;
align-items: center;
color: var(--blue);
background-color: var(--blue-semi);
height: toRem(3);
width: toRem(3);
border-radius: 50%;
margin-right: toRem(0.5);
}
.desktop {
display: flex;
}
@media (max-width: toRem(76.8)) {
.desktop {
display: none;
}
}
</style>

View File

@@ -0,0 +1,162 @@
<template>
<div :class="['nav-list', { 'menu-open': !menuIsClosed }]">
<ul class="responsive">
<li class="logged-link link-first">
<Link
:text="$t('general.header.contribute_text')"
:route="{ name: 'why-contribute' }"
look="link--blue-dark"
@click.native="$emit('triggerClose')"
/>
</li>
<li class="logged-link">
<Link
:text="$t('general.header.upload_text')"
look="button button--blue"
:route="{ name: 'upload-pictures' }"
@click.native="$emit('triggerClose')"
/>
</li>
</ul>
<div class="separator responsive"></div>
<ul>
<li class="logged-link responsive">
<Link
:text="$t('general.header.sequences_text')"
:route="{ name: 'my-sequences' }"
:image="{
url: 'icon/photos.svg',
alt: $t('general.header.alt_photos')
}"
look="link--blue-dark"
@click.native="$emit('triggerClose')"
/>
</li>
<li class="logged-link desktop">
<Link
:text="$t('general.header.contribute_text')"
:route="{ name: 'why-contribute' }"
:image="{
url: 'icon/photos.svg',
alt: $t('general.header.alt_photos')
}"
look="link--blue-dark"
@click.native="$emit('triggerClose')"
/>
</li>
<li v-if="userProfileUrlLength" class="logged-link">
<Link
:route="{ name: 'my-information' }"
:image="{
url: 'icon/information.svg',
alt: $t('general.header.alt_information')
}"
:text="$t('general.header.my_information_text')"
look="link--blue-dark"
@click.native="$emit('triggerClose')"
/>
</li>
<li class="logged-link">
<Link
:route="{ name: 'my-settings' }"
:image="{
url: 'icon/settings.svg',
alt: $t('general.header.alt_logo')
}"
:text="$t('general.header.my_settings_text')"
look="link--blue-dark"
@click.native="$emit('triggerClose')"
/>
</li>
<li class="logged-link">
<Link
type="external"
:text="$t('general.header.logout_text')"
:image="{
url: 'icon/logout.svg',
alt: $t('general.header.alt_logout')
}"
:path-external="getAuthRoute('auth/logout', route.path)"
look="link--blue-dark"
@click.native="$emit('triggerClose')"
/>
</li>
</ul>
</div>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router'
import { getAuthRoute } from '@/utils/auth'
const route = useRoute()
import Link from '@/components/Link.vue'
defineProps({
menuIsClosed: { type: Boolean, default: true },
userProfileUrlLength: { type: Number, default: 0 }
})
</script>
<style scoped lang="scss">
ul {
margin: 0;
padding: toRem(2) 0;
}
.nav-list {
display: none;
flex-direction: column;
justify-content: center;
align-items: initial;
position: absolute;
width: toRem(25);
top: toRem(8);
right: 0;
z-index: 2;
background-color: var(--white);
box-shadow: 0 toRem(0.2) toRem(0.4) rgb(0 0 0 / 10%);
border-radius: toRem(1);
padding: toRem(1) toRem(2);
}
.separator {
height: toRem(0.1);
background-color: var(--grey);
width: 100%;
margin-top: toRem(1);
margin-bottom: toRem(0.5);
}
.menu-open {
display: flex;
}
.logged-link {
padding: toRem(1);
display: flex;
}
.link-first {
margin-bottom: toRem(1);
}
.logged-link:hover {
border-radius: toRem(0.5);
background-color: var(--grey);
}
.responsive {
display: none;
}
.desktop {
display: flex;
}
@media (max-width: toRem(76.8)) {
.nav-list {
top: toRem(11);
width: 100%;
border-radius: initial;
}
.desktop {
display: none;
}
.responsive {
display: block;
}
.logged-link {
padding: toRem(0);
}
}
</style>

View File

@@ -0,0 +1,43 @@
<template>
<div class="wrapper-card">
<img :src="img(imgSrc)" :alt="imgAlt" class="image" />
<h2 class="subtitle">{{ title }}</h2>
<p class="description">{{ description }}</p>
</div>
</template>
<script lang="ts" setup>
import { img } from '../../utils/image'
defineProps({
title: { type: String, default: null },
description: { type: String, default: null },
imgSrc: { type: String, default: null },
imgAlt: { type: String, default: null }
})
</script>
<style lang="scss" scoped>
.wrapper-card {
display: flex;
flex-direction: column;
}
.subtitle {
@include text(h2);
max-width: toRem(25);
color: var(--blue-dark);
}
.image {
height: toRem(7);
width: fit-content;
margin-bottom: toRem(1);
}
.description {
margin: 0;
color: var(--grey-dark);
}
@media (max-width: toRem(76.8)) {
.subtitle {
max-width: 100%;
}
}
</style>

View File

@@ -1,131 +0,0 @@
<template>
<section :class="['information-section', { 'first-sequence': index === 0 }]">
<div class="uploaded-pictures">
<p v-if="index === 0" class="title-current-upload">
{{ $t('pages.upload.sequence_uploading_title') }}
</p>
<p v-if="sequence.pictures" class="uploaded-title">
<span
>{{ $t('pages.upload.import') }} {{ sequence.title }} -
{{ sequence.pictures.length }}/{{ sequence.pictureCount }}</span
>
</p>
<ul class="uploaded-picture-list">
<PictureItem
v-for="picture in uploadPictures"
:text="$t('pages.upload.uploaded_word')"
:name="picture.name"
look="success"
>
<i class="bi bi-check-circle"></i>
</PictureItem>
</ul>
<div v-if="sequence.id" class="wrapper-button-sequence">
<Link
:text="$t('pages.upload.sequence_link')"
look="button button--white"
target="_blank"
:route="{ name: 'sequence', params: { id: sequence.id } }"
/>
</div>
</div>
<div class="errors-pictures">
<p v-if="uploadErrors.length" class="uploaded-title">
{{ uploadErrors.length }} {{ $t('pages.upload.error_word') }}
</p>
<ul class="uploaded-error-list">
<PictureItem
v-for="error in uploadErrors"
:text="error.message"
:name="error.name"
look="error"
/>
</ul>
</div>
</section>
</template>
<script setup lang="ts">
import type { PropType } from 'vue'
import Link from '@/components/Link.vue'
import PictureItem from '@/components/upload/PictureItem.vue'
import type { uploadErrorInterface } from '@/views/interfaces/UploadPicturesView'
defineProps({
index: { type: Number, default: 0 },
sequence: { type: Object, default: {} },
picturesCount: { type: Number, default: null },
uploadErrors: {
type: Array as PropType<uploadErrorInterface[]>,
default: []
},
uploadPictures: {
type: Array as PropType<uploadErrorInterface[]>,
default: []
}
})
</script>
<style scoped lang="scss">
.information-section {
display: flex;
margin-bottom: toRem(4);
padding-top: toRem(2);
padding-bottom: toRem(2);
width: 80%;
box-shadow: 0px 6.45694px 8.60925px rgba(0, 0, 0, 0.05);
}
.first-sequence {
background-color: var(--blue-pale);
border-radius: toRem(0.5);
}
.uploaded-pictures,
.errors-pictures {
width: 50%;
}
.title-current-upload {
margin-bottom: toRem(2);
@include text(m-regular);
color: var(--blue-dark);
margin-left: toRem(2);
}
.uploaded-title {
margin-left: toRem(2);
margin-bottom: toRem(2);
width: 100%;
color: var(--grey-semi-dark);
font-weight: bold;
@include text(s-regular);
}
.uploaded-picture-list {
padding-left: 0;
}
.uploaded-picture-list,
.uploaded-error-list {
padding: 0rem toRem(2) toRem(2);
overflow-y: auto;
max-height: toRem(35);
}
.bi-check-circle {
color: var(--green);
font-size: toRem(2);
}
.wrapper-button-sequence {
padding-top: toRem(2);
width: fit-content;
margin: auto;
}
.errors-pictures {
padding-left: toRem(2);
padding-right: toRem(2);
.uploaded-title {
margin-top: toRem(4);
}
}
@media (max-width: toRem(76.8)) {
.uploaded-pictures,
.errors-pictures {
width: 100%;
padding: 0;
}
}
</style>

View File

@@ -1,63 +1,96 @@
<template>
<div class="wrapper-loader">
<div class="loader">
<span class="loader-percentage">{{ loadPercentage }}</span>
<Loader look="lg" :is-loaded="isLoaded" />
<div class="entry-loader">
<div class="wrapper-loader">
<div v-if="uploadedSequence" class="loader-title">
<span class="title">{{ uploadedSequence.title }}</span>
<div class="sequence-button">
<Link
:text="$t('pages.upload.sequence_link')"
:disabled="!isLoaded"
:route="{ name: 'sequence', params: { id: uploadedSequence.id } }"
look="button button--blue-bleu"
/>
</div>
</div>
<p v-if="isLoaded" class="text-information">
{{ $t('pages.upload.sequence_loaded_information') }}
</p>
<p v-else class="text-information">
{{ $t('pages.upload.sequence_loading_information') }}
</p>
<div v-if="!isLoaded" class="loading-block">
<div class="loader">
<span class="loader-percentage">{{ loadPercentage }}</span>
<Loader look="md" :is-loaded="isLoaded" />
</div>
<div v-if="uploadedSequence" class="loader-information">
<div class="wrapper-picture-count">
<span class="picture-length">{{
uploadedSequence.pictures.length
}}</span>
<span> / </span>
<span>{{ picturesCount }}</span>
</div>
<span>{{ $t('pages.upload.images_count_text') }}</span>
</div>
</div>
<div v-else class="loaded-block">
<img src="@/assets/images/success.svg" alt="" />
<p>{{ $t('pages.upload.upload_done') }}</p>
</div>
</div>
<div v-if="loadPercentage === '100%'" class="wrapper-button-new-upload">
<div
v-if="uploadedSequence && uploadedSequence.picturesOnError.length"
class="error-wrapper"
>
<div class="error-corpus">
<i class="bi bi-exclamation-triangle"></i>
<span class="error-text">{{
$t('pages.upload.pictures_error', {
count: uploadedSequence.picturesOnError.length
})
}}</span>
</div>
<Button
:text="$t('pages.upload.button_new_upload')"
look="button button--blue"
@trigger="$emit('triggerNewUpload')"
:text="$t('pages.upload.error_button')"
look="button button--red"
@trigger="$emit('triggerModal')"
/>
</div>
<div v-if="uploadedSequences[0]" class="loader-information">
<span class="loader-title">{{ uploadPendingTitle }}</span>
<span v-if="loadPercentage !== '100%'" class="loader-text">{{
$t('pages.upload.upload_pending_pictures', { count: picturesCount })
}}</span>
<span class="loader-text-size"
>{{ uploadedSequences[0].pictureSize }}/{{ loadTextSize }}
</span>
<span class="loader-text-warning">{{
$t('pages.upload.leave_message')
}}</span>
</div>
</div>
</template>
<script setup lang="ts">
import Loader from '@/components/Loader.vue'
import Link from '@/components/Link.vue'
import Button from '@/components/Button.vue'
import { computed } from 'vue'
import type { PropType } from 'vue'
import type { sequenceInterface } from '@/views/interfaces/UploadPicturesView'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const props = defineProps({
import type { SequenceInterface } from '@/views/interfaces/UploadPicturesView'
defineProps({
loadPercentage: { type: String, default: '0%' },
loadTextSize: { type: String, default: '0 Mo' },
isLoaded: { type: Boolean, default: false },
uploadedSequences: {
type: Array as PropType<sequenceInterface[]>,
default: []
uploadedSequence: {
type: Object as PropType<SequenceInterface | null>,
default: null
},
picturesCount: { type: Number, default: null }
})
const uploadPendingTitle = computed<string>(() => {
if (props.loadPercentage !== '100%') return t('pages.upload.upload_pending')
return t('pages.upload.upload_done')
})
</script>
<style scoped lang="scss">
.entry-loader {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 93%;
}
.wrapper-loader {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-top: toRem(4);
margin-top: toRem(3);
height: 100%;
}
.loader {
position: relative;
@@ -69,40 +102,79 @@ const uploadPendingTitle = computed<string>(() => {
width: toRem(10);
position: absolute;
text-align: center;
@include text(h1);
@include text(xxl-regular);
color: var(--blue);
}
.wrapper-button-new-upload {
display: flex;
justify-content: center;
}
.loader-information {
margin-top: toRem(2);
display: flex;
align-items: center;
flex-direction: column;
}
.loader-title,
.loader-text,
.loader-text-size {
text-align: center;
@include text(s-regular);
}
.loader-title {
@include text(h2);
margin-bottom: toRem(0.5);
width: 100%;
@include text(m-regular);
color: var(--blue-dark);
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: toRem(1);
}
.loader-text {
.sequence-button {
width: fit-content;
}
.text-information {
@include text(s-r-regular);
margin-bottom: toRem(4);
width: 100%;
}
.wrapper-picture-count {
@include text(xxl-regular);
}
.picture-length {
color: var(--blue);
border-bottom: toRem(0.1) solid var(--grey);
font-weight: 860;
}
.loader-text-size {
color: var(--grey-semi-dark);
.error-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
border-left: toRem(1.4) solid var(--red-pale);
background-color: var(--orange-pale);
padding: toRem(2);
border-radius: toRem(1.5);
}
.loader-text-warning {
text-align: center;
@include text(s-regular);
color: var(--orange);
margin-top: toRem(1);
width: toRem(31);
.error-corpus {
color: var(--red-pale);
@include text(m-regular);
margin-bottom: toRem(1);
}
.error-text {
margin-left: toRem(0.5);
}
.loading-block,
.loaded-block {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.loaded-block {
color: var(--green);
img {
margin-bottom: toRem(2);
}
}
@media (max-width: toRem(102.4)) {
.loader-title {
flex-direction: column;
align-items: flex-start;
}
.title {
margin-bottom: toRem(1.5);
}
}
</style>

View File

@@ -6,31 +6,29 @@
"description": "Panoramax, lalternative libre pour photo-cartographier les territoires"
},
"header": {
"contribute_text": "À propos",
"upload_text": "Contribuer",
"login_text": "Connexion",
"register_text": "Inscription",
"contribute_text": "Pourquoi contribuer ?",
"my_account": "Mon compte",
"upload_text": "+ Partager des photos",
"sequences_text": "Mes photos",
"alt_logo": "Logo de l'instance",
"title": "Instance\nPanoramax",
"alt_photos": "Icone représentant des photos",
"alt_information": "Icone représentant un utilisateur",
"alt_settings": "Icone des paramètres",
"alt_logout": "Icone représentant un bouton de déconnexion",
"title": "Panoramax",
"beta_text": "Version beta",
"logout_text": "Déconnexion",
"my_information_text": "Mes informations",
"my_settings_text": "Mes paramètres",
"login_text": "Connexion",
"burger_menu_aria_label_open": "Afficher le menu",
"burger_menu_aria_label_closed": "Masquer le menu"
},
"footer": {
"panoramax_title": "Panoramax",
"panoramax_site": "Site vitrine",
"panoramax_faq": "FAQ",
"information_title": "Ressources",
"information_forum": "Forum",
"information_gitlab": "Gitlab",
"information_github": "Github",
"rs_title": "Suivez-nous",
"mastodon_alt": "Logo Mastodon",
"linkedin_alt": "Logo Linkedin",
"twitter_alt": "Logo Twitter",
"panoramax_site": "Découvrir Panoramax.fr",
"information_gitlab": "Voir le code",
"gitlab_logo": "Logo Gitlab",
"ay11_text": "Accessibilité : non conforme"
},
"error_text": "Une erreur est survenue",
@@ -80,53 +78,100 @@
"sequence_name": "Nom",
"sequence_photos": "Photos",
"sequence_date": "Prise de vue",
"sequence_creation": "Versement",
"sequence_status": "Statut",
"sequence_published": "Publiée",
"sequence_waiting": "En cours de publication",
"sequence_hidden": "Masquée",
"sequence_published": "Publiée",
"sequence_waiting": "En cours de publication",
"sequence_hidden": "Masquée",
"no_sequences_text": "Vous n'avez pas encore de photos publiées \uD83D\uDE22",
"button_upload": "Partager vos photos",
"sequence_deleted": "La séquence a bien été supprimée"
},
"share_pictures": {
"title": "Partagez vos photos",
"sub_title": "Un compte utilisateur est obligatoire pour partager des photos",
"photo_type1": "Des lieux visibles depuis la voie publique",
"photo_type2": "360° ou non",
"photo_type3": "Vues du sol",
"photo_type4": "Géolocalisées",
"description": "Ici, vos photos sont accessibles à tous :\n\n{check} automatiquement floutées dans le respect de <a href='https://panoramax.fr/foire-aux-questions' target='_blank' style='color:black'>la législation</a>\n{check} libres de droit, <a href={licenseUrl} target='_blank' style='color:black'>sous licence {licenseName}</a>\n{check} sous forme «brute» pour des réutilisations variées (ex: préparation des chantiers)\n\n",
"footer_block": "⚠️️️ Aujourd'hui, le versement de grands volumes d'images est possible via une ligne de commande et via une interface web.",
"button": "Accéder à l'outil",
"alt_img_upload": "Image qui représente plusieurs photos en cours de téléchargement",
"title_terminal": "Utilisez la ligne de commande",
"footer_description_terminal": "Les données déposées seront sous {word}",
"cli_title": "Vous voulez accéder à plus de documentation ?",
"user_account_button": "Créer un compte",
"title": "Pourquoi contribuer à la base de photographies de Panoramax ?",
"description": "Panoramax a pour ambition de devenir le Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"alt_img_map": "Illustration d'une femme qui regarde une carte avec son smartphone geolocalisé",
"card_photo1": "Des lieux visibles depuis la voie publique",
"card_photo2": "Des photos publiées au format 360° ou non",
"card_photo3": "Une fonctionnalité de visualisation vue du sol",
"card_photo4": "Des photos géolocalisées en temps réel",
"card_alt_photo1": "Image qui représente un immeuble",
"card_alt_photo2": "Image qui représente des photos 360 degrés",
"card_alt_photo3": "Image qui représente une carte avec un pointeur",
"card_alt_photo4": "Image qui représente un pointeur",
"card_description1": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"card_description2": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"card_description3": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"card_description4": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"upload_subtitle": "Chargez vos images simplement en ligne",
"upload_illustration_alt": "Illustration qui représente l'envoie de photo en ligne",
"upload_description": "Panoramax a pour ambition de devenir le Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
"upload_button": "+ Partager des images",
"command_line_subtitle": "L'outil en ligne de commande",
"description_terminal": "<a href='https://gitlab.com/geovisio/cli' target='_blank' style='color:black'>L'outil en ligne de commande</a> vous permet de partager de grands volumes de photos. La procédure est simple et vous devez disposer <a target='_blank' href='https://www.python.org/downloads/' style='color:black'>de python (au moins la version 3.8)</a>.\n\n1. Installer loutil en ligne de commande geovisio\n2. Lancez la commande de versement dimages sur le dossier choisi. Après '--api-url', renseignez l'url de l'api de l'instance où partager les photos et le chemin vers votre dossier de photos sur votre machine. Loutil demandera vos informations de connexion avant l'import. Une fois les données chargées, un temps de traitement est nécessaire pour les rendre disponibles.",
"terminal_install": "pip install geovisio_cli",
"terminal_text": "geovisio upload --api-url {url} <DOSSIER_PHOTOS>",
"button_copy": "Copier"
"button_copy": "Copier",
"information_subtitle": "Ici, vos photos sont accessibles à tous : ",
"information_text1": "automatiquement floutées dans le respect de la législation",
"information_text2": "Les données déposées seront sous {word}",
"information_text3": "sous forme «brute» pour des réutilisations variées (ex: préparation des chantiers)",
"information_about_title": "A propos du chargement d'images",
"information_about_description": "Aujourd'hui, le versement de grands volumes d'images est possible via une ligne de commande. Une interface d'upload est également utilisable pour des volumes moins importants. Bientôt, d'autres moyens de versement seront disponibles.",
"doc_subtitle": "Vous voulez accéder à plus de documentation technique ?",
"doc_description": "Nous mettons à disposition un outil recensant lensemble de la documentation technique relative à Panoramax.",
"doc_button": "Voir à la documentation technique",
"doc_illustration_alt": "Illustration représentant un personnage avec un feuillet de documents"
},
"upload": {
"title": "Déposez vos photos",
"input_label": "Déposez des photos dans la zone ou ",
"import_word": "importez",
"title": "Contribuez à la base de photographies de Panoramax",
"description": "Pour les très gros volumes de photos, nous mettons à votre disposition un outil en ligne de commande.",
"know_more_button": "En savoir plus",
"input_label": "Glissez vos images ici ou cliquez sur ",
"import_word": "importer",
"import_type": "Format JPEG uniquement",
"subtitle_import": "Dépôt des images",
"text_import": "Déposez vos fichiers dans cet espace, chaque image ou série dimages constitue une “séquence”. Vous pourrez ensuite les retrouver dans la section “mes images”",
"subtitle_process": "Traitements de l'import",
"uploading_process": "Téléchargement en cours...",
"sequence_title": "Séquence du ",
"button_text": "Envoyer",
"uploaded_files": "{count} fichier| {count} fichiers",
"no_uploaded_files": "Aucun fichier sélectionné",
"uploaded_word": " Image téléchargée",
"import": "Imports",
"error_word": "Images en erreur",
"sequence_uploading_title": "Dernier import",
"upload_pending": "Transfert en cours...",
"upload_done": "Transfert terminé !",
"upload_pending_pictures": "Envoi de {count} photo en cours |Envoi de {count} photos en cours",
"sequence_link": "Voir la sequence",
"button_new_upload": "Nouvel envoi",
"leave_message": "⚠️ Attention, le téléchargement sera interrompu si vous quittez la page avant la fin."
"images_count_text": "Images chargées",
"no_img_text": "aucune image chargée actuellement",
"upload_done": "Le chargement de la séquence est terminé",
"sequence_link": "Accéder à cette séquence",
"pictures_error": "{count} image n'a pas pu être chargée| {count} image n'ont pas pu être chargées",
"sequence_loading_information": "Une fois chargée, la séquence sera en traitement et accessible sur Panoramax dans les prochaines minutes.",
"sequence_loaded_information": "La séquence est chargée et est en cours de traitement. Elle sera accessible sur Panoramax dans quelques minutes.",
"leave_message": "⚠️ Attention, le téléchargement sera interrompu si vous quittez la page avant la fin.",
"error_button": "Afficher les erreurs",
"modal_error_title": "Liste des photos non chargés"
},
"ay11": {
"title": "Déclaration daccessibilité",
"date": "Établie le 18 septembre 2023.",
"introduction": "IGN sengage à rendre son service accessible, conformément à larticle 47 de la loi n° 2005-102 du 11 février 2005.\n Cette déclaration daccessibilité sapplique à Panoramax Instance IGN : https://panoramax.ign.fr",
"subtitle_conformity": "État de conformité",
"conformity_text": "Panoramax Instance IGN est non conforme avec le ",
"conformity_text2": "Le site na encore pas été audité.",
"subtitle_conformity2": "Contenus non accessibles",
"subtitle_increase": "Amélioration et contact",
"increase_text": "Si vous narrivez pas à accéder à un contenu ou à un service, vous pouvez\n contacter le responsable de Panoramax Instance IGN pour être orienté vers une alternative accessible ou obtenir le contenu sous une autre forme.",
"phone": "Téléphone : +33 14 398 84 61",
"email_text": "E-mail :",
"email": "signalement.ign@panoramax.fr",
"address": "Adresse : IGN, Saint-Mandé",
"increase_info": "Nous essayons de répondre dans les 5 jours ouvrés.",
"subtitle_to_do": "Voie de recours",
"to_do_text": "Cette procédure est à utiliser dans le cas suivant : vous avez signalé au responsable du site internet un défaut daccessibilité qui vous\n empêche daccéder à un contenu ou à un des services du portail et vous navez pas obtenu de réponse satisfaisante. \n vous pouvez :",
"write_message": "Écrire un message au",
"defenseur_droits": "Défenseur des droits",
"contact": "Contacter",
"contact_text": "le délégué du Défenseur des droits dans votre région",
"send_letter": "Envoyer un courrier par la poste (gratuit, ne pas mettre de\n timbre):\n Défenseur des droits\n Libre réponse 71120 75342 Paris CEDEX 07",
"end": "Cette déclaration daccessibilité a été créé le\n 18 septembre 2023 grâce au",
"generator_betagouv": "Générateur de Déclaration dAccessibilité de BetaGouv"
}
}
}

View File

@@ -10,7 +10,6 @@ import { pinia } from './store'
import fr from './locales/fr.json'
import './assets/main.scss'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap/dist/js/bootstrap.js'
import 'bootstrap-icons/font/bootstrap-icons.css'
import 'geovisio/build/index.css'

View File

@@ -44,8 +44,8 @@ const routes: Array<RouteRecordRaw> = [
},
{ path: '/sequence/:id', name: 'sequence', component: MySequenceView },
{
path: '/partager-des-photos',
name: 'share-pictures',
path: '/pourquoi-contribuer',
name: 'why-contribute',
component: SharePicturesView
},
{
@@ -67,7 +67,6 @@ router.beforeResolve(
const siteLoggedRoutes =
to.name === 'my-settings' ||
to.name === 'my-sequences' ||
to.name === 'sequence' ||
to.name === 'upload-pictures'
if (siteLoggedRoutes) {

View File

@@ -1,6 +1,6 @@
import { it, describe, expect } from 'vitest'
import { shallowMount } from '@vue/test-utils'
import BetaText from '../../../components/BetaText.vue'
import BetaText from '../../../components/InstanceName.vue'
import { createI18n } from 'vue-i18n'
import fr from '../../../locales/fr.json'

View File

@@ -1,13 +1,10 @@
import { vi, it, beforeEach, describe, expect } from 'vitest'
import { shallowMount } from '@vue/test-utils'
import { shallowMount, mount } from '@vue/test-utils'
import { createI18n } from 'vue-i18n'
import { createRouter, createWebHistory } from 'vue-router'
import { useCookies } from 'vue3-cookies'
import fr from '../../../locales/fr.json'
import Header from '../../../components/Header.vue'
import MyInformation from '../../../views/MyInformationView.vue'
import MySettings from '../../../views/MySettingsView.vue'
import SharePictures from '../../../views/SharePicturesView.vue'
vi.mock('vue-router')
vi.mock('vue3-cookies', () => {
const mockCookies = {
@@ -36,28 +33,65 @@ const router = createRouter({
describe('Template', () => {
describe('When the user is not logged', () => {
it('should render the component with good wording keys', async () => {
import.meta.env.VITE_API_URL = 'api-url/'
const wrapper = shallowMount(Header, {
global: {
plugins: [i18n, router],
mocks: {
$t: (msg) => msg
describe('When the user is in desktop', () => {
it('should render the component with the desktop entries', async () => {
import.meta.env.VITE_API_URL = 'api-url/'
const wrapper = mount(Header, {
global: {
plugins: [i18n, router],
mocks: {
$t: (msg) => msg
}
}
}
})
expect(wrapper.html()).contains('class="wrapper-logo desktop"')
expect(wrapper.html()).contains('logo.jpeg"')
expect(wrapper.html()).contains('class="wrapper-instance"')
expect(wrapper.html()).contains('general.header.title')
expect(wrapper.html()).contains(
'class="desktop" data-test="button-login-desktop"'
)
expect(wrapper.html()).contains('api-url/api/auth/login')
expect(wrapper.html()).contains('general.header.login_text')
expect(wrapper.html()).contains('general.header.register_text')
})
expect(wrapper.html()).contains('general.header.contribute_text')
})
it('should render the component login link', async () => {
const wrapper = shallowMount(Header, {
global: {
plugins: [i18n, router],
mocks: {
$t: (msg) => msg
describe('When the user is in mobile', () => {
it('should render the component with the responsive entries', async () => {
import.meta.env.VITE_API_URL = 'api-url/'
const wrapper = mount(Header, {
global: {
plugins: [i18n, router],
mocks: {
$t: (msg) => msg
}
}
}
})
expect(wrapper.html()).contains('class="responsive entry-instance"')
expect(wrapper.html()).contains('general.header.title')
expect(wrapper.html()).contains('class="wrapper-logo responsive"')
expect(wrapper.html()).contains('logo.jpeg')
expect(wrapper.html()).contains(
'class="responsive" data-test="button-login-responsive"'
)
expect(wrapper.html()).contains('api-url/api/auth/login')
expect(wrapper.html()).contains('general.header.login_text')
expect(wrapper.html()).contains('general.header.register_text')
})
})
describe('When the user is in desktop OR in mobile', () => {
it('should render the component with the commons entries', async () => {
import.meta.env.VITE_API_URL = 'api-url/'
const wrapper = mount(Header, {
global: {
plugins: [i18n, router],
mocks: {
$t: (msg) => msg
}
}
})
expect(wrapper.html()).contains('general.header.contribute_text')
})
expect(wrapper.html()).contains('api/auth/login')
})
})
describe('When the user is logged', () => {
@@ -77,11 +111,12 @@ describe('Template', () => {
}
}
})
expect(wrapper.html()).contains('general.header.contribute_text')
expect(wrapper.html()).contains('general.header.my_information_text')
expect(wrapper.html()).contains('general.header.logout_text')
expect(wrapper.html()).contains('<header-open')
expect(wrapper.html()).contains('general.header.sequences_text')
expect(wrapper.html()).contains('general.header.my_settings_text')
expect(wrapper.html()).contains('general.header.upload_text')
expect(wrapper.html()).contains('data-test="link-logged-upload"')
expect(wrapper.html()).contains('<account-button')
expect(wrapper.html()).contains('username="UI"')
})
})
})

View File

@@ -0,0 +1,38 @@
import { it, describe, expect } from 'vitest'
import { shallowMount } from '@vue/test-utils'
import AccountButton from '../../../../components/header/AccountButton.vue'
import i18n from '../../config'
describe('Template', () => {
describe('Props', () => {
it('should have default props', () => {
const wrapper = shallowMount(AccountButton, {
global: {
plugins: [i18n]
}
})
expect(wrapper.vm.menuIsClosed).toBe(true)
expect(wrapper.vm.isLogged).toBe(false)
expect(wrapper.vm.userName).toBe(null)
expect(wrapper.vm.ariaLabel).toBe(null)
})
it('should have all props filled', () => {
const wrapper = shallowMount(AccountButton, {
global: {
plugins: [i18n]
},
props: {
menuIsClosed: false,
isLogged: true,
userName: 'User',
ariaLabel: 'label'
}
})
expect(wrapper.html()).contains('aria-label="label"')
expect(wrapper.html()).contains('class="wrapper-name"')
expect(wrapper.html()).contains('User')
expect(wrapper.html()).contains('Mon compte')
expect(wrapper.html()).contains('class="arrow-img arrow-up"')
})
})
})

View File

@@ -0,0 +1,75 @@
import { vi, it, describe, expect } from 'vitest'
import { shallowMount } from '@vue/test-utils'
import HeaderOpen from '../../../../components/header/HeaderOpen.vue'
import i18n from '../../config'
import { createRouter, createWebHistory } from 'vue-router/dist/vue-router'
vi.mock('vue-router')
const router = createRouter({
history: createWebHistory(),
routes: []
})
describe('Template', () => {
describe('Props', () => {
it('should have default props', () => {
const wrapper = shallowMount(HeaderOpen, {
global: {
plugins: [i18n, router]
}
})
expect(wrapper.vm.menuIsClosed).toBe(true)
expect(wrapper.vm.userProfileUrlLength).toBe(0)
})
describe('When all the props are filled', () => {
describe('When the user is in desktop', () => {
it('should render the desktop entries', () => {
const wrapper = shallowMount(HeaderOpen, {
global: {
plugins: [i18n, router]
},
props: {
menuIsClosed: false,
userProfileUrlLength: 5
}
})
expect(wrapper.html()).contains('class="logged-link desktop"')
expect(wrapper.html()).contains('text="Pourquoi contribuer ?"')
})
})
describe('When the user is in mobile', () => {
it('should render the responsive entries', () => {
const wrapper = shallowMount(HeaderOpen, {
global: {
plugins: [i18n, router]
},
props: {
menuIsClosed: false,
userProfileUrlLength: 5
}
})
expect(wrapper.html()).contains('class="logged-link responsive"')
expect(wrapper.html()).contains('text="Mes photos"')
expect(wrapper.html()).contains('class="separator responsive"')
})
})
it('should render all the commons entries', () => {
import.meta.env.VITE_API_URL = 'api-url/'
const wrapper = shallowMount(HeaderOpen, {
global: {
plugins: [i18n, router]
},
props: {
menuIsClosed: false,
userProfileUrlLength: 5
}
})
expect(wrapper.html()).contains('text="Pourquoi contribuer ?"')
expect(wrapper.html()).contains('text="+ Partager des photos"')
expect(wrapper.html()).contains('text="Mes informations"')
expect(wrapper.html()).contains('text="Mes paramètres"')
expect(wrapper.html()).contains('text="Déconnexion"')
expect(wrapper.html()).contains('api/auth/logout')
})
})
})
})

View File

@@ -1,111 +0,0 @@
import { it, describe, expect } from 'vitest'
import { shallowMount } from '@vue/test-utils'
import ImportedSection from '../../../../components/upload/ImportedSection.vue'
import i18n from '../../config'
describe('Template', () => {
describe('Props', () => {
it('should have default props', () => {
const wrapper = shallowMount(ImportedSection, {
global: {
plugins: [i18n]
}
})
expect(wrapper.vm.index).toBe(0)
expect(wrapper.vm.sequence).toStrictEqual({})
expect(wrapper.vm.picturesCount).toBe(null)
expect(wrapper.vm.uploadErrors).toStrictEqual([])
expect(wrapper.vm.uploadPictures).toStrictEqual([])
})
})
describe('When the index is 0', () => {
it('should have a specific class and wordings', () => {
const wrapper = shallowMount(ImportedSection, {
global: {
plugins: [i18n]
},
props: {
index: 0
}
})
expect(wrapper.html()).contains(
'class="information-section first-sequence"'
)
expect(wrapper.html()).contains('Dernier impor')
})
})
describe('When the sequence have pictures', () => {
it('should have a title', () => {
const wrapper = shallowMount(ImportedSection, {
global: {
plugins: [i18n]
},
props: {
sequence: {
id: 'id132435',
title: 'my title',
pictureCount: 3,
pictures: [{ id: 'id' }]
}
}
})
expect(wrapper.html()).contains('class="uploaded-title"')
expect(wrapper.html()).contains('Imports my title - 1/3')
})
it('should have a Link', () => {
const wrapper = shallowMount(ImportedSection, {
global: {
plugins: [i18n]
},
props: {
sequence: {
id: 'id132435',
title: 'my title',
pictureCount: 3,
pictures: [{ id: 'id' }]
}
}
})
expect(wrapper.html()).contains('<link-stub')
expect(wrapper.html()).contains('text="Voir la sequence"')
})
})
describe('When there are uploaded pictures', () => {
it('should have a list of pictures', () => {
const wrapper = shallowMount(ImportedSection, {
global: {
plugins: [i18n]
},
props: {
uploadPictures: [{ name: 'my name1' }, { name: 'my name2' }]
}
})
expect(wrapper.html()).contains('name="my name1"')
expect(wrapper.html()).contains('name="my name2"')
expect(wrapper.html()).contains('text=" Image téléchargée"')
expect(wrapper.html()).contains('look="success"')
expect(wrapper.html()).contains('<picture-item-stub')
})
})
describe('When there are uploaded errors', () => {
it('should have a list of errors', () => {
const wrapper = shallowMount(ImportedSection, {
global: {
plugins: [i18n]
},
props: {
uploadErrors: [
{ name: 'my name1', message: 'my message1' },
{ name: 'my name2', message: 'my message2' }
]
}
})
expect(wrapper.html()).contains('name="my name1"')
expect(wrapper.html()).contains('name="my name2"')
expect(wrapper.html()).contains('text="my message1"')
expect(wrapper.html()).contains('text="my message2"')
expect(wrapper.html()).contains('look="error"')
expect(wrapper.html()).contains('<picture-item-stub')
})
})
})

View File

@@ -12,56 +12,66 @@ describe('Template', () => {
}
})
expect(wrapper.vm.loadPercentage).toBe('0%')
expect(wrapper.vm.loadTextSize).toBe('0 Mo')
expect(wrapper.vm.isLoaded).toBe(false)
expect(wrapper.vm.picturesCount).toBe(null)
expect(wrapper.vm.uploadedSequences).toStrictEqual([])
expect(wrapper.vm.uploadedSequence).toStrictEqual(null)
})
})
describe('When the component have a percentage equal to 100%', () => {
it('should have a button to do a new upload', () => {
const wrapper = shallowMount(UploadLoader, {
global: {
plugins: [i18n]
},
props: {
loadPercentage: '100%'
}
})
expect(wrapper.html()).contains('button-stub')
expect(wrapper.html()).contains('text="Nouvel envoi"')
})
})
describe('When the component have an uploaded sequence', () => {
it('should render the uploaded sequences information', () => {
const wrapper = shallowMount(UploadLoader, {
global: {
plugins: [i18n]
},
props: {
uploadedSequences: [{ pictureSize: '2345 Mo' }],
loadTextSize: '2345 Mo',
loadPercentage: '97%'
}
})
expect(wrapper.html()).contains('Transfert en cours...')
expect(wrapper.html()).contains('2345 Mo/2345 Mo')
})
describe('When the loading is completed', () => {
it('should render the loading ended information', () => {
const wrapper = shallowMount(UploadLoader, {
global: {
plugins: [i18n]
},
props: {
uploadedSequences: [{ pictureSize: '2345 Mo' }],
loadTextSize: '2345 Mo',
loadPercentage: '100%'
}
describe('When some props are filled', () => {
describe('When the loader is loading', () => {
it('should have a loading state', () => {
const wrapper = shallowMount(UploadLoader, {
global: {
plugins: [i18n]
},
props: {
loadPercentage: '50%',
picturesCount: 1,
uploadedSequence: {
title: 'Séquence du 5 octobre 2023, 11:25:51',
id: '3e8ee06aa190bea',
pictures: [{}, {}],
picturesOnError: []
}
}
})
expect(wrapper.html()).contains('text="Accéder à cette séquence"')
expect(wrapper.html()).contains('disabled="true"')
expect(wrapper.html()).contains(
'Une fois chargée, la séquence sera en traitement et accessible sur Panoramax dans les prochaines minutes.'
)
expect(wrapper.html()).contains('class="loader-percentage">50%')
expect(wrapper.html()).contains('<loader')
expect(wrapper.html()).contains('look="md"')
expect(wrapper.html()).contains('class="picture-length">2')
})
})
describe('When the loader is loaded', () => {
it('should have a loading state', () => {
const wrapper = shallowMount(UploadLoader, {
global: {
plugins: [i18n]
},
props: {
loadPercentage: '50%',
picturesCount: 1,
uploadedSequence: {
title: 'Séquence du 5 octobre 2023, 11:25:51',
id: '3e8ee06caaa190bea',
pictures: [{}, {}],
picturesOnError: []
},
isLoaded: true
}
})
expect(wrapper.html()).contains('text="Accéder à cette séquence"')
expect(wrapper.html()).contains('disabled="false"')
expect(wrapper.html()).contains(
'La séquence est chargée et est en cours de traitement. Elle sera accessible sur Panoramax dans quelques minutes.'
)
expect(wrapper.html()).contains(
'Le chargement de la séquence est terminé'
)
})
expect(wrapper.html()).contains('text="Nouvel envoi"')
expect(wrapper.html()).contains('Transfert terminé !')
expect(wrapper.html()).contains('2345 Mo/2345 Mo')
})
})
})

View File

@@ -5,11 +5,7 @@ import {
spliceIntoChunks,
formatPaginationItems
} from '../../views/utils/sequence/index'
import {
formatPictureSize,
formatTextSize,
sortByName
} from '../../views/utils/upload/index'
import { sortByName } from '../../views/utils/upload/index'
import { getAuthRoute } from '../../utils/auth'
import { img } from '../../utils/image'
import { title } from '../../utils/index'
@@ -116,26 +112,6 @@ describe('formatPaginationItems', () => {
})
})
describe('formatPictureSize', () => {
it('should render the size number', () => {
const size = 560673
expect(formatPictureSize(size)).toEqual(1)
})
})
describe('formatTextSize', () => {
const size = 2260121
it('should render the size text formated in ko', () => {
expect(formatTextSize(size, 1)).toEqual('2207.15 Ko')
})
it('should render the size text formated in mo', () => {
expect(formatTextSize(size, 2)).toEqual('2.16 Mo')
})
it('should render the size text formated in go', () => {
expect(formatTextSize(size, 3)).toEqual('0 Go')
})
})
describe('getAuthRoute', () => {
it('should render auth route', () => {
import.meta.env.VITE_API_URL = 'my-url/'

View File

@@ -1,210 +0,0 @@
import { it, describe, expect, vi, beforeEach } from 'vitest'
import { flushPromises, shallowMount } from '@vue/test-utils'
import MySequencesView from '../../../views/MySequencesView.vue'
import axios from 'axios'
import { createI18n } from 'vue-i18n'
import fr from '../../../locales/fr.json'
import Button from '../../../components/Button.vue'
import { createRouter, createWebHistory } from 'vue-router'
import { createTestingPinia } from '@pinia/testing'
vi.mock('../../../utils/dates', () => ({
formatDate: vi.fn()
}))
vi.mock('axios')
const i18n = createI18n({
locale: 'fr',
fallbackLocale: 'fr',
globalInjection: true,
legacy: false,
messages: {
fr
}
})
const router = createRouter({
history: createWebHistory(),
routes: []
})
const mockResponseSequences = [
{
href: 'https://my-link',
rel: 'self',
type: 'application/json'
},
{
href: 'https://my-link',
id: 'my-id',
rel: 'child',
'stats:items': { count: 16 },
title: 'ma sequence 1',
extent: {
temporal: {
interval: [['2022-09-22T08:03:08+00:00', '2022-09-22T08:03:08+00:00']]
}
}
}
]
describe('Template', () => {
it('should render the view without sequences', async () => {
vi.spyOn(axios, 'get').mockResolvedValue({ data: { links: [] } })
const wrapper = shallowMount(MySequencesView, {
global: {
plugins: [i18n, router, createTestingPinia({ createSpy: vi.fn })],
mocks: {
$t: (msg) => msg
}
}
})
await flushPromises()
expect(axios.get).toHaveBeenCalledWith('api/users/me/catalog')
expect(wrapper.vm.userSequences).toEqual([])
expect(wrapper.html()).contains('general.header.upload_text')
})
it('should render the view with a loader loading', async () => {
const wrapper = shallowMount(MySequencesView, {
global: {
plugins: [i18n, router, createTestingPinia({ createSpy: vi.fn })],
mocks: {
$t: (msg) => msg
}
}
})
await flushPromises()
expect(axios.get).toHaveBeenCalledWith('api/users/me/catalog')
expect(wrapper.vm.userSequences).toEqual([])
expect(wrapper.html()).contains('general.header.upload_text')
})
it('should render the view with a sequence in the list', async () => {
vi.spyOn(axios, 'get').mockResolvedValue({
data: { links: mockResponseSequences }
})
const wrapper = shallowMount(MySequencesView, {
global: {
plugins: [i18n, createTestingPinia({ createSpy: vi.fn })],
mocks: {
$t: (msg) => msg
}
}
})
wrapper.vm.isLoading = true
await wrapper.vm.$nextTick()
expect(wrapper.html()).contains('<loader')
})
})
describe('Methods', () => {
const mockResponseSequencesToSort = [
{
href: 'https://my-link',
id: 'my-id',
rel: 'child',
'stats:items': { count: 16 },
title: 'za sequence 1',
extent: {
temporal: {
interval: [['2030-09-22T08:03:08+00:00', '2022-09-22T08:03:08+00:00']]
}
}
},
{
href: 'https://my-link',
id: 'my-id',
rel: 'child',
'stats:items': { count: 2 },
title: 'ma sequence 1',
extent: {
temporal: {
interval: [['2022-09-22T08:03:08+00:00', '2022-09-22T08:03:08+00:00']]
}
}
}
]
beforeEach(async () => {
await axios.get.mockReturnValue({
data: { links: mockResponseSequencesToSort }
})
await flushPromises()
})
describe('sortAlpha', () => {
it('should should sort sequences by title', async () => {
const wrapper = shallowMount(MySequencesView, {
global: {
plugins: [i18n, router, createTestingPinia({ createSpy: vi.fn })],
mocks: {
$t: (msg) => msg
},
components: {
Button
}
}
})
wrapper.vm.isLoading = false
await wrapper.vm.$nextTick()
const spy = vi.spyOn(wrapper.vm, 'sortAlpha')
const buttonWrapper = wrapper.findComponent(
'[data-test="button-sort-title"]'
)
await buttonWrapper.vm.$emit('trigger')
expect(spy).toHaveBeenCalledWith('title')
expect(wrapper.vm.userSequences[0]).toEqual(
mockResponseSequencesToSort[1]
)
})
})
describe('sortNum', () => {
it('should should sort sequences by number of pictures', async () => {
const wrapper = shallowMount(MySequencesView, {
global: {
plugins: [i18n, router, createTestingPinia({ createSpy: vi.fn })],
mocks: {
$t: (msg) => msg
},
components: {
Button
}
}
})
wrapper.vm.isLoading = false
await wrapper.vm.$nextTick()
const spy = vi.spyOn(wrapper.vm, 'sortNum')
const buttonWrapper = wrapper.findComponent(
'[data-test="button-sort-number"]'
)
await buttonWrapper.vm.$emit('trigger')
expect(spy).toHaveBeenCalledWith('num')
expect(wrapper.vm.userSequences[0]).toEqual(
mockResponseSequencesToSort[1]
)
})
it('should should sort sequences by date', async () => {
const wrapper = shallowMount(MySequencesView, {
global: {
plugins: [i18n, router, createTestingPinia({ createSpy: vi.fn })],
mocks: {
$t: (msg) => msg
},
components: {
Button
}
}
})
wrapper.vm.isLoading = false
await wrapper.vm.$nextTick()
const spy = vi.spyOn(wrapper.vm, 'sortNum')
const buttonWrapper = wrapper.findComponent(
'[data-test="button-sort-date"]'
)
await buttonWrapper.vm.$emit('trigger')
expect(spy).toHaveBeenCalledWith('date')
expect(wrapper.vm.userSequences[0]).toEqual(
mockResponseSequencesToSort[1]
)
})
})
})

View File

@@ -52,7 +52,7 @@ describe('Template', () => {
expect(wrapper.html()).contains('icon="bi bi-eye"')
expect(wrapper.html()).contains('look="no-text"')
expect(wrapper.html()).contains(
'icon="bi bi-clipboard-plus" disabled="false" isloading="false" text="pages.share_pictures.button_copy" tooltip="" look="button--white"'
'icon="bi bi-clipboard-plus" disabled="false" isloading="false" text="pages.share_pictures.button_copy" tooltip="" look="button--white background-white"'
)
})
})

View File

@@ -1,60 +1,33 @@
import { it, describe, expect, vi } from 'vitest'
import { shallowMount, mount, flushPromises } from '@vue/test-utils'
import { shallowMount, mount } from '@vue/test-utils'
import UploadPicturesView from '../../../views/UploadPicturesView.vue'
import { createRouter, createWebHistory } from 'vue-router'
import i18n from '../config'
import InputUpload from '../../../components/InputUpload.vue'
import * as createAPictureToASequence from '@/views/utils/upload/request'
import * as createASequence from '@/views/utils/upload/request'
import { formatDate } from '../../../utils/dates'
import * as sortByName from '../../../views/utils/upload/index'
const router = createRouter({
history: createWebHistory(),
routes: []
})
describe('Template', () => {
it('should render the view with the input upload and the good wordings', () => {
const wrapper = shallowMount(UploadPicturesView, {
global: {
plugins: [i18n, router],
plugins: [i18n],
mocks: {
$t: (msg) => msg
}
}
})
expect(wrapper.html()).contains('pages.upload.title')
expect(wrapper.html()).contains('pages.upload.description')
expect(wrapper.html()).contains('<input-upload-stub')
expect(wrapper.html()).contains('pages.upload.input_label')
expect(wrapper.html()).contains('<button-stub')
expect(wrapper.html()).contains('text="pages.upload.button_text"')
})
describe('trigger addPictures', () => {
it('should trigger to add pictures', async () => {
const wrapper = shallowMount(UploadPicturesView, {
global: {
plugins: [i18n, router],
mocks: {
$t: (msg) => msg
},
components: {
InputUpload
}
}
})
const spy = vi.spyOn(wrapper.vm, 'addPictures')
const sortByNameMock = vi.spyOn(sortByName, 'sortByName')
sortByNameMock.mockReturnValue([{}, {}])
const wrapperInputUpload = await wrapper.findComponent(InputUpload)
await wrapperInputUpload.trigger('trigger')
await wrapperInputUpload.vm.$emit('trigger', [{}, {}])
expect(spy).toHaveBeenCalledTimes(1)
expect(wrapper.html()).contains('2 fichiers')
})
describe('submit uploadPicture', () => {
it('should trigger to uploadPictures', async () => {
const wrapper = mount(UploadPicturesView, {
global: {
plugins: [i18n, router],
plugins: [i18n],
mocks: {
$t: (msg) => msg
},
@@ -63,23 +36,27 @@ describe('Template', () => {
}
}
})
const spy = vi.spyOn(wrapper.vm, 'uploadPicture')
const sortByNameMock = vi.spyOn(sortByName, 'sortByName')
sortByNameMock.mockReturnValue([{}, {}])
const wrapperInputUpload = wrapper.findComponent(InputUpload)
await wrapperInputUpload.trigger('trigger')
await wrapperInputUpload.vm.$emit('trigger', [{}, {}])
const buttonWrapper = await wrapper.find('[data-test="button-upload"]')
await buttonWrapper.trigger('submit.prevent')
expect(spy).toHaveBeenCalledTimes(1)
expect(wrapper.html()).contains('class="wrapper-uploading"')
expect(wrapper.html()).contains('pages.upload.uploading_process')
expect(wrapper.html()).contains('class="uploading-img"')
expect(wrapper.html()).contains('class="loader-percentage"')
expect(wrapper.html()).contains('class="lds-ring lg"')
})
})
describe('one sequence has been imported', () => {
it('should render a sequence with a list of uploaded pictures', async () => {
const wrapper = mount(UploadPicturesView, {
global: {
plugins: [i18n, router],
stubs: {
modal: {
template: '<div></div>'
}
},
plugins: [i18n],
mocks: {
$t: (msg) => msg
}
@@ -103,7 +80,7 @@ describe('Template', () => {
spyPicture.mockReturnValue({ data: {} })
const sequenceTitle = `Séquence du ${formatDate(
new Date(),
'Do MMMM YYYY, HH:mm:ss'
'Do MMMM YYYY, hh:mm:ss'
)}`
const body = new FormData()
body.append('position', '1')
@@ -111,21 +88,10 @@ describe('Template', () => {
const wrapperInputUpload = wrapper.findComponent(InputUpload)
await wrapperInputUpload.trigger('trigger')
await wrapperInputUpload.vm.$emit('trigger', [picture])
const buttonWrapper = await wrapper.find('[data-test="button-upload"]')
await buttonWrapper.trigger('submit.prevent')
expect(spyASequence).toHaveBeenCalledWith(sequenceTitle)
expect(spyPicture).toHaveBeenCalledWith(sequenceId, body)
expect(wrapper.html()).contains('class="uploaded-picture-list"')
expect(wrapper.html()).contains('class="uploaded-picture-item success"')
expect(wrapper.html()).contains(
'100MSDCF_DSC02790.JPG - pages.upload.uploaded_word'
)
expect(wrapper.html()).contains('<router-link')
expect(wrapper.html()).contains(
'class="default button button--white" title="pages.upload.sequence_link"'
)
expect(wrapper.html()).contains('class="loader-percentage">0%')
})
})
})

View File

@@ -1,81 +1,63 @@
<template>
<main class="entry-page">
<h1>Déclaration daccessibilité</h1>
<p>Établie le <span>18 septembre 2023</span>.</p>
<h1>{{ $t('pages.ay11.title') }}</h1>
<p>{{ $t('pages.ay11.date') }}</p>
<p>
<span>IGN</span> sengage à rendre son service accessible, conformément à
larticle 47 de la loi n° 2005-102 du 11 février 2005.
{{ $t('pages.ay11.introduction') }}
</p>
<h2>{{ $t('pages.ay11.subtitle_conformity') }}</h2>
<p>
Cette déclaration daccessibilité sapplique à
<strong>Panoramax Instance IGN</strong
><span> (<span>https://panoramax.ign.fr</span>)</span>.
</p>
<h2>État de conformité</h2>
<p>
<strong>Panoramax Instance IGN</strong> est
<strong><span data-printfilter="lowercase">non conforme</span></strong>
avec le
{{ $t('pages.ay11.conformity_text') }}
<abbr title="Référentiel général damélioration de laccessibilité"
>RGAA</abbr
>. <span>Le site na encore pas été audité.</span>
>RGAA.</abbr
>. <span>{{ $t('pages.ay11.conformity_text2') }}</span>
</p>
<h2>Contenus non accessibles</h2>
<h2>Amélioration et contact</h2>
<h2>{{ $t('pages.ay11.subtitle_conformity2') }}</h2>
<h2>{{ $t('pages.ay11.subtitle_increase') }}</h2>
<p>
Si vous narrivez pas à accéder à un contenu ou à un service, vous pouvez
contacter le responsable de <span>Panoramax Instance IGN</span> pour être
orienté vers une alternative accessible ou obtenir le contenu sous une
autre forme.
{{ $t('pages.ay11.increase_text') }}
</p>
<ul class="basic-information feedback h-card">
<li>Téléphone&nbsp;: <span>+33 14 398 84 61</span></li>
<li>{{ $t('pages.ay11.phone') }}</li>
<li>
E-mail&nbsp;:
{{ $t('pages.ay11.email_text') }}
<a
href="mailto:camille.salou@ign.frpanoramax@panoramax.frsignalement.ign@panoramax.fr"
>signalement.ign@panoramax.fr</a
>{{ $t('pages.ay11.email') }}</a
>
</li>
<li>Adresse&nbsp;: <span>IGN, Saint-Mandé</span></li>
<li>{{ $t('pages.ay11.address') }}</li>
</ul>
<p>Nous essayons de répondre dans les <span>5 jours ouvrés</span>.</p>
<h2>Voie de recours</h2>
<p>{{ $t('pages.ay11.increase_info') }}</p>
<h2>{{ $t('pages.ay11.subtitle_to_do') }}</h2>
<p>
Cette procédure est à utiliser dans le cas suivant&nbsp;: vous avez
signalé au responsable du site internet un défaut daccessibilité qui vous
empêche daccéder à un contenu ou à un des services du portail et vous
navez pas obtenu de réponse satisfaisante.
{{ $t('pages.ay11.subtitle_to_do') }}
</p>
<p>Vous pouvez&nbsp;:</p>
<ul>
<li>
Écrire un message au
<a href="https://formulaire.defenseurdesdroits.fr/"
>Défenseur des droits</a
>
{{ $t('pages.ay11.write_message') }}
<a href="https://formulaire.defenseurdesdroits.fr/">{{
$t('pages.ay11.defenseur_droits')
}}</a>
</li>
<li>
Contacter
<a href="https://www.defenseurdesdroits.fr/saisir/delegues"
>le délégué du Défenseur des droits dans votre région</a
>
{{ $t('pages.ay11.contact') }}
<a href="https://www.defenseurdesdroits.fr/saisir/delegues">{{
$t('pages.ay11.contact_text')
}}</a>
</li>
<li>
Envoyer un courrier par la poste (gratuit, ne pas mettre de
timbre)&nbsp;:<br />
Défenseur des droits<br />
Libre réponse 71120 75342 Paris CEDEX 07
{{ $t('pages.ay11.send_letter') }}
</li>
</ul>
<hr />
<p>
Cette déclaration daccessibilité a été créé le
<span>18 septembre 2023</span> grâce au
<a href="https://betagouv.github.io/a11y-generateur-declaration/#create"
>Générateur de Déclaration dAccessibilité de BetaGouv</a
>.
{{ $t('pages.ay11.end') }}
<a
href="https://betagouv.github.io/a11y-generateur-declaration/#create"
>{{ $t('pages.ay11.generator_betagouv') }}</a
>
</p>
</main>
</template>
@@ -85,6 +67,16 @@
<style scoped lang="scss">
.entry-page {
padding: toRem(5) toRem(2);
@include text(m-r-regular);
color: var(--grey-dark);
}
h1 {
@include text(h1);
color: var(--blue-dark);
}
h2 {
@include text(h1);
color: var(--blue-dark);
}
@media (max-width: toRem(50)) {
.entry-page {

View File

@@ -1,96 +1,28 @@
<template>
<main class="entry-page">
<section id="viewer" class="entry-viewer"></section>
<section :class="['entry-section', focus]">
<Viewer ref="viewerRef" />
</section>
</main>
</template>
<script lang="ts" setup>
import { useI18n } from 'vue-i18n'
import { onMounted, ref } from 'vue'
import 'geovisio/build/index.css'
import GeoVisio from 'geovisio'
import { createLink } from '@/components-viewer/reportLink'
import { createUrlLink } from '@/utils/index'
import type { ViewerMapInterface } from '@/views/interfaces/common'
import { getIgnTiles } from '@/utils/mapAndViewer'
import { ref, watchEffect } from 'vue'
import Viewer from '@/components/Viewer.vue'
const emit = defineEmits<{ (e: 'trigger', value: string): void }>()
const viewerRef = ref<any>(null)
let focus = ref<string>('focus-map')
const { t } = useI18n()
let mapIsLoaded = ref<boolean>(false)
let viewer = ref()
onMounted(async () => {
const reportLink = document.createElement('div')
reportLink.className = 'gvs-group gvs-group-large gvs-group-btnpanel'
const tiles = import.meta.env.VITE_TILES
const maxZoom = import.meta.env.VITE_MAX_ZOOM
const zoom = import.meta.env.VITE_ZOOM
const center = import.meta.env.VITE_CENTER
let paramsGeovisio: ViewerMapInterface = {
map: {
startWide: true
}
}
if (center && center !== '') {
const centerMap = center.split(',').map((el: string) => parseInt(el))
paramsGeovisio = {
map: {
...paramsGeovisio.map,
center: centerMap
}
}
}
if (zoom && zoom !== '') {
paramsGeovisio = {
map: {
...paramsGeovisio.map,
zoom: parseFloat(zoom)
}
}
}
if (maxZoom && maxZoom !== '') {
paramsGeovisio = {
map: {
...paramsGeovisio.map,
maxZoom: parseInt(maxZoom)
}
}
}
if (tiles) {
const style = tiles.includes('wxs.ign.fr') ? await getIgnTiles() : tiles
paramsGeovisio = {
map: {
...paramsGeovisio.map,
style
}
}
}
try {
viewer.value = await new GeoVisio(
'viewer', // Div ID
`${import.meta.env.VITE_API_URL}/api/search`,
{
...paramsGeovisio,
widgets: { customWidget: reportLink }
watchEffect(() => {
if (viewerRef.value && viewerRef.value.viewer) {
viewerRef.value.viewer.addEventListener(
'focus-changed',
(e: { detail: { focus: string } }) => {
if (e.detail.focus === 'pic') focus.value = 'focus-pic'
else focus.value = 'focus-map'
emit('trigger', focus.value)
}
)
if (viewer.value && viewer.value.addEventListener) {
viewer.value.addEventListener(
'picture-loaded',
async (e: { detail: { picId: string } }): Promise<void> => {
const href = t('pages.home.report_mail', {
picId: e.detail.picId,
link: createUrlLink(e.detail.picId)
})
reportLink.innerHTML = createLink(
href,
t('pages.home.report_button_text')
)
}
)
}
mapIsLoaded.value = true
} catch (err) {
console.log(err)
}
})
</script>
@@ -98,33 +30,25 @@ onMounted(async () => {
.entry-page {
display: flex;
}
.entry-viewer {
font-size: initial;
width: 100vw;
position: relative;
min-height: calc(100vh - #{toRem(27.42)});
.entry-section {
width: 100%;
}
.focus-pic {
height: calc(100vh - #{toRem(8)});
}
.focus-map {
height: calc(100vh - #{toRem(13.2)});
}
.gvs-focus-map .entry-report-button {
display: none;
}
@media (max-width: toRem(50)) {
@media (max-width: toRem(76.8)) {
.entry-page {
padding-top: toRem(11);
overflow: hidden;
}
@supports (-webkit-touch-callout: none) {
/* CSS specific to iOS devices */
.entry-viewer {
min-height: -webkit-fill-available;
min-height: moz-available;
min-height: fill-available;
}
}
@supports not (-webkit-touch-callout: none) {
/* CSS for other than iOS devices */
.entry-viewer {
min-height: calc(100vh - #{toRem(17)});
}
.entry-section {
height: calc(100vh - #{toRem(11)});
}
}
</style>

View File

@@ -7,7 +7,12 @@
@trigger="menuIsOpen = !menuIsOpen"
/>
</div>
<section id="viewer" class="entry-viewer"></section>
<section class="entry-viewer">
<Viewer
:fetch-options="{ fetchOptions: { credentials: 'include' } }"
ref="viewerRef"
/>
</section>
<div v-if="sequence && !isLoading" class="menu-right">
<div class="menu-top" ref="collapseMenu">
<div class="header-menu">
@@ -31,7 +36,7 @@
{{ sequence.title }}
</h1>
</div>
<div class="wrapper-button">
<div v-if="isSequenceOwner" class="wrapper-button">
<Button
:tooltip="$t('pages.sequence.hide_sequence_tooltip')"
:text="
@@ -39,7 +44,7 @@
? $t('pages.sequence.button_disable')
: $t('pages.sequence.button_enable')
"
look="button--white"
look="button--white background-white"
:icon="
sequence.status === 'ready' ? 'bi bi-eye-slash' : 'bi bi-eye'
"
@@ -49,7 +54,7 @@
<Button
:tooltip="$t('pages.sequence.delete_sequence_tooltip')"
:text="$t('pages.sequence.button_delete')"
look="button--red"
look="button--red background-white"
icon="bi bi-trash"
@trigger="deleteCollection"
/>
@@ -103,7 +108,7 @@
</div>
</div>
<div v-if="pictures && pictures.length" class="photos-wrapper">
<div class="delete-all" ref="deleteAll">
<div v-if="isSequenceOwner" class="delete-all" ref="deleteAll">
<div class="wrapper-select">
<InputCheckbox
:is-checked="pictures.length === picturesToDelete.length"
@@ -120,7 +125,7 @@
</div>
<div class="action-buttons">
<Button
look="button--white"
look="button--white background-white"
:icon="
picturesToDeleteStatus === 'hidden' ||
imagesSelectedHaveDifferentStatus
@@ -135,7 +140,7 @@
/>
<div class="button-hidde">
<Button
look="button--red"
look="button--red background-white"
icon="bi bi-trash"
:tooltip="$t('pages.sequence.delete_photo_tooltip')"
:disabled="!picturesToDelete.length"
@@ -147,7 +152,7 @@
<ul class="photo-list">
<li
v-for="(item, i) in pictures"
:id="`photo${i}`"
:id="`el-list${i}`"
class="photo-item"
>
<ImageItem
@@ -188,13 +193,14 @@ import { useRoute, useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { useSequenceStore } from '@/store/sequence'
import { storeToRefs } from 'pinia'
import { useCookies } from 'vue3-cookies'
import Button from '@/components/Button.vue'
import Toast from '@/components/Toast.vue'
import Pagination from '@/components/Pagination.vue'
import InputCheckbox from '@/components/InputCheckbox.vue'
import Loader from '@/components/Loader.vue'
import ImageItem from '@/components/ImageItem.vue'
import 'geovisio/build/index.css'
import Viewer from '@/components/Viewer.vue'
import { durationCalc, formatDate } from '@/utils/dates'
import {
deleteACollectionItem,
@@ -213,7 +219,6 @@ import {
spliceIntoChunks,
formatPaginationItems
} from '@/views/utils/sequence/index'
import { getIgnTiles } from '@/utils/mapAndViewer'
import type {
ResponseUserPhotoInterface,
ResponseUserPhotoLinksInterface,
@@ -221,10 +226,7 @@ import type {
UserSequenceInterface,
ResponseUserSequenceInterface
} from './interfaces/MySequenceView'
import type { ViewerMapInterface } from '@/views/interfaces/common'
import GeoVisio from 'geovisio'
import { createUrlLink } from '@/utils'
import { createLink } from '@/components-viewer/reportLink'
const { cookies } = useCookies()
const { t } = useI18n()
const route = useRoute()
@@ -241,10 +243,10 @@ let headerPanelIsOpen = ref<boolean>(true)
let isShiftPressed = ref<boolean>(false)
let itemSelected = ref<string>('')
let isLoading = ref<boolean>(false)
let viewer = ref()
const collapseMenu = ref<HTMLDivElement>()
const deleteAll = ref<HTMLDivElement>()
const menuHeight = ref<string>()
const viewerRef = ref()
onMounted(async () => {
try {
@@ -264,62 +266,13 @@ onMounted(async () => {
(el) => el.properties['geovisio:status'] === 'ready'
)
pictures.value = collectionItems
const tiles = import.meta.env.VITE_TILES
const maxZoom = import.meta.env.VITE_MAX_ZOOM
let paramsGeovisio: ViewerMapInterface = {
map: {
startWide: true
}
}
if (maxZoom) {
paramsGeovisio = {
map: {
...paramsGeovisio.map,
maxZoom: parseInt(maxZoom)
}
}
}
if (tiles) {
const style = tiles.includes('wxs.ign.fr') ? await getIgnTiles() : tiles
paramsGeovisio = {
map: {
...paramsGeovisio.map,
style
}
}
}
const reportLink = document.createElement('div')
reportLink.className = 'gvs-group gvs-group-large gvs-group-btnpanel'
viewer.value = await new GeoVisio(
'viewer', // Div ID
`${import.meta.env.VITE_API_URL}/api/search`,
{
...paramsGeovisio,
fetchOptions: {
credentials: 'include'
},
widgets: { customWidget: reportLink }
}
)
if (viewer.value && viewer.value.addEventListener) {
viewer.value.addEventListener(
'picture-loaded',
async (e: { detail: { picId: string } }): Promise<void> => {
const href = t('pages.home.report_mail', {
picId: e.detail.picId,
link: createUrlLink(e.detail.picId)
})
reportLink.innerHTML = createLink(
href,
t('pages.home.report_button_text')
)
}
)
}
setHeightValue()
if (itemSelected.value.length || !collectionItemsReady[0]) return
viewer.value._api.onceReady().then(() => {
viewer.value.goToPicture(collectionItemsReady[0].id, sequence.value?.id)
viewerRef.value.viewer._api.onceReady().then(() => {
viewerRef.value.viewer.goToPicture(
collectionItemsReady[0].id,
sequence.value?.id
)
})
itemSelected.value = collectionItemsReady[0].id
scrollIntoSelected(collectionItemsReady[0].id, pictures.value)
@@ -329,8 +282,8 @@ onMounted(async () => {
})
watchEffect(async () => {
if (!viewer.value || !viewer.value.addEventListener) return
viewer.value.addEventListener(
if (!viewerExist(viewerRef)) return
viewerRef.value.viewer.addEventListener(
'picture-loaded',
async (e: { detail: { picId: string } }): Promise<void> => {
if (itemSelected.value === e.detail.picId) return
@@ -343,6 +296,20 @@ watchEffect(async () => {
)
})
function viewerExist(viewerRef: any): boolean {
return !!(viewerRef && viewerRef.value && viewerRef.value.viewer)
}
const isSequenceOwner = computed((): boolean => {
return !!(
sequence.value &&
sequence.value.providers &&
sequence.value.providers[0] &&
cookies.get('user_name') &&
sequence.value.providers[0].name === cookies.get('user_name')
)
})
const sequenceStatus = computed((): string => {
if (sequence.value?.status === 'ready')
return t('pages.sequence.sequence_published')
@@ -455,7 +422,7 @@ async function patchCollection(): Promise<void> {
const { data } = await fetchCollectionItems(route.params.id, '?limit=100')
pictures.value = data.features
}
viewer.value.reloadVectorTiles()
viewerRef.value.viewer.reloadVectorTiles()
isLoading.value = false
}
@@ -523,7 +490,7 @@ async function selectImageAndMove(
picturesToDelete.value.length < 2 &&
item.properties['geovisio:status'] === 'ready'
) {
const viewerMap = await viewer.value
const viewerMap = await viewerRef.value.viewer
viewerMap.goToPicture(item.id, sequence.value?.id)
itemSelected.value = item.id
await goToTheGoodPage(item.id)
@@ -587,8 +554,8 @@ async function patchOrDeleteCollectionItems(
const { data } = await fetchCollectionItems(route.params.id, '?limit=100')
pictures.value = data.features
isLoading.value = false
viewer.value.reloadVectorTiles()
viewer.value.goToPicture(pictures.value[0].id, route.params.id)
viewerRef.value.viewer.reloadVectorTiles()
viewerRef.value.viewer.goToPicture(pictures.value[0].id, route.params.id)
scrollIntoSelected(picturesToDelete.value[0], pictures.value)
picturesToDelete.value = []
sequenceStore.addToastText(t('general.success_text'), 'success')
@@ -800,6 +767,15 @@ async function patchOrDeleteCollectionItems(
}
}
@media (max-width: toRem(76.8)) {
.entry-page {
padding-top: toRem(11.6);
}
.entry-viewer {
height: calc(100vh - #{toRem(11.6)});
}
.menu-right {
height: calc(100vh - #{toRem(12)});
}
.desktop {
display: none;
}
@@ -850,6 +826,10 @@ async function patchOrDeleteCollectionItems(
.photo-selected-separator {
display: none;
}
.entry-pagination {
margin-top: toRem(0.5);
margin-bottom: toRem(1);
}
}
@media (max-width: toRem(50)) {
@@ -909,7 +889,7 @@ async function patchOrDeleteCollectionItems(
}
}
@media (min-width: 1900px) {
@media (min-width: toRem(190)) {
.menu-right {
width: initial;
max-width: toRem(100);

View File

@@ -1,154 +1,193 @@
<template>
<main class="entry-page">
<h1 class="sequences-title">{{ $t('pages.sequences.title') }}</h1>
<ul v-if="!isLoading" class="sequence-list">
<li class="sequence-item">
<div class="sequence-header-item"></div>
<div class="sequence-header-item">
<Button
:text="$t('pages.sequences.sequence_name')"
look="link--grey"
icon="bi bi-arrow-down-up"
data-test="button-sort-title"
@trigger="sortAlpha('title')"
/>
</div>
<div class="sequence-header-item">
<Button
:text="$t('pages.sequences.sequence_photos')"
look="link--grey"
icon="bi bi-arrow-down-up"
data-test="button-sort-number"
@trigger="sortNum('num')"
/>
</div>
<div class="sequence-header-item">
<Button
:text="$t('pages.sequences.sequence_date')"
look="link--grey"
icon="bi bi-arrow-down-up"
data-test="button-sort-date"
@trigger="sortNum('date')"
/>
</div>
<div class="sequence-header-item">
<Button
:text="$t('pages.sequences.sequence_status')"
look="link--grey"
icon="bi bi-arrow-down-up"
data-test="button-sort-date"
@trigger="sortAlpha('geovisio:status')"
/>
</div>
</li>
<li
v-if="userSequences.length"
v-for="item in userSequences"
class="sequence-item"
>
<router-link
class="button-item"
:to="{
name: 'sequence',
params: { id: item.id }
}"
>
<div class="wrapper-thumb">
<img
v-if="item['stats:items'].count > 0"
:src="`${item.href}/thumb.jpg`"
lazy="loading"
alt=""
class="thumb"
<section class="section-viewer">
<Viewer
:fetch-options="{
fetchOptions: {
credentials: 'include'
}
}"
:sequence-id="seqId"
:geovisio-viewer="false"
ref="viewerRef"
/>
</section>
<section class="section-sequence">
<h1 class="sequences-title">{{ $t('pages.sequences.title') }}</h1>
<ul v-if="!isLoading" class="sequence-list">
<li class="sequence-item">
<div class="sequence-header-item"></div>
<div class="sequence-header-item">
<Button
:text="$t('pages.sequences.sequence_name')"
look="link--grey"
icon="bi bi-arrow-down-up"
data-test="button-sort-title"
@trigger="sortAlpha('title')"
/>
<div class="wrapper-thumb-hover">
</div>
<div class="sequence-header-item">
<Button
:text="$t('pages.sequences.sequence_photos')"
look="link--grey"
icon="bi bi-arrow-down-up"
data-test="button-sort-number"
@trigger="sortNum('num')"
/>
</div>
<div class="sequence-header-item">
<Button
:text="$t('pages.sequences.sequence_date')"
look="link--grey"
icon="bi bi-arrow-down-up"
data-test="button-sort-date"
@trigger="sortNum('date')"
/>
</div>
<div class="sequence-header-item">
<Button
:text="$t('pages.sequences.sequence_creation')"
look="link--grey"
icon="bi bi-arrow-down-up"
data-test="button-sort-date"
@trigger="sortNum('date', 'created')"
/>
</div>
<div class="sequence-header-item">
<Button
:text="$t('pages.sequences.sequence_status')"
look="link--grey"
icon="bi bi-arrow-down-up"
data-test="button-sort-date"
@trigger="sortAlpha('geovisio:status')"
/>
</div>
</li>
<li
v-if="userSequences.length"
v-for="(item, i) in userSequences"
:id="`el-list${i}`"
class="sequence-item"
@mouseover="goToSequence(item)"
>
<router-link
:class="[
'button-item',
item.id === seqId ? 'button-item-hover' : ''
]"
:to="{
name: 'sequence',
params: { id: item.id }
}"
>
<div class="wrapper-thumb">
<img
v-if="item['stats:items'].count > 0"
:src="`${item.href}/thumb.jpg`"
lazy="loading"
alt=""
class="thumb-hover"
class="thumb"
/>
<div class="wrapper-thumb-hover">
<img
v-if="item['stats:items'].count > 0"
:src="`${item.href}/thumb.jpg`"
lazy="loading"
alt=""
class="thumb-hover"
/>
</div>
</div>
</div>
<div>
<span>
{{ item.title }}
</span>
</div>
<div>
<i class="bi bi-images"></i>
<span>
{{ item['stats:items'].count }}
</span>
</div>
<div>
<span>
{{
formatDate(
item.extent.temporal.interval[0][0],
'Do MMMM YYYY HH:mm:ss'
)
}}
</span>
</div>
<div>
<span>{{ sequenceStatus(item['geovisio:status']) }}</span>
</div>
</router-link>
</li>
<div v-else class="no-sequence">
<p class="no-sequence-text">
{{ $t('pages.sequences.no_sequences_text') }}
</p>
<Link
:text="$t('general.header.upload_text')"
look="button"
:route="{ name: 'share-pictures' }"
/>
<div>
<span>
{{ item.title }}
</span>
</div>
<div>
<i class="bi bi-images"></i>
<span>
{{ item['stats:items'].count }}
</span>
</div>
<div>
<span>
{{
formatDate(
item.extent.temporal.interval[0][0],
'Do MMMM YYYY HH:mm:ss'
)
}}
</span>
</div>
<div>
<span>
{{ formatDate(item.created, 'Do MMMM YYYY HH:mm:ss') }}
</span>
</div>
<div>
<span :class="item['geovisio:status']">{{
sequenceStatus(item['geovisio:status'])
}}</span>
</div>
</router-link>
</li>
<div v-else class="no-sequence">
<p class="no-sequence-text">
{{ $t('pages.sequences.no_sequences_text') }}
</p>
<Link
:text="$t('general.header.upload_text')"
look="button button--blue"
:route="{ name: 'why-contribute' }"
/>
</div>
</ul>
<div v-else class="loader">
<Loader look="sm" :is-loaded="false" />
</div>
</ul>
<div v-else class="loader">
<Loader look="sm" :is-loaded="false" />
</div>
</section>
<Toast :text="toastText" :look="toastLook" @trigger="toastText = ''" />
</main>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { onMounted, ref, watchEffect } from 'vue'
import { useI18n } from 'vue-i18n'
import { useSequenceStore } from '@/store/sequence'
import { storeToRefs } from 'pinia'
import { scrollIntoSelected } from '@/views/utils/sequence/index'
import axios from 'axios'
import Viewer from '@/components/Viewer.vue'
import Button from '@/components/Button.vue'
import Link from '@/components/Link.vue'
import Toast from '@/components/Toast.vue'
import Loader from '@/components/Loader.vue'
import type {
LinkInterface,
ExtentLinkInterface
SequenceLinkInterface,
ExtentSequenceLinkInterface
} from './interfaces/MySequencesView'
import { formatDate } from '@/utils/dates'
const { t } = useI18n()
const sequenceStore = useSequenceStore()
const { toastText, toastLook } = storeToRefs(sequenceStore)
let userSequences = ref<LinkInterface[]>([])
let userSequences = ref<SequenceLinkInterface[]>([])
let collectionBbox = ref<number[]>([])
let isSorted = ref<boolean>(false)
let isLoading = ref<boolean>(false)
let seqId = ref<string>('')
const viewerRef = ref<any>(null)
function sequenceStatus(status: string): string {
if (status === 'ready') return t('pages.sequences.sequence_published')
if (status === 'waiting-for-process')
return t('pages.sequences.sequence_waiting')
return t('pages.sequences.sequence_hidden')
if (status === 'hidden') return t('pages.sequences.sequence_hidden')
return t('pages.sequences.sequence_waiting')
}
function sortAlpha<TKey extends keyof LinkInterface>(key: TKey): void {
function sortAlpha<TKey extends keyof SequenceLinkInterface>(key: TKey): void {
const sorted = userSequences.value.sort(
(
a: { [K in TKey]: LinkInterface[TKey] },
b: { [K in TKey]: LinkInterface[TKey] }
a: { [K in TKey]: SequenceLinkInterface[TKey] },
b: { [K in TKey]: SequenceLinkInterface[TKey] }
) => {
if (a[key] < b[key]) return !isSorted.value ? -1 : 1
if (a[key] > b[key]) return !isSorted.value ? 1 : -1
@@ -158,12 +197,16 @@ function sortAlpha<TKey extends keyof LinkInterface>(key: TKey): void {
isSorted.value = !isSorted.value
userSequences.value = sorted
}
function sortNum(type: string): void {
function sortNum(type: string, dateToSort?: string): void {
let aa, bb: number
const sorted = userSequences.value.sort(
(a: ExtentLinkInterface, b: ExtentLinkInterface) => {
(a: ExtentSequenceLinkInterface, b: ExtentSequenceLinkInterface) => {
aa = new Date(a.extent.temporal.interval[0][0]).getTime()
bb = new Date(b.extent.temporal.interval[0][0]).getTime()
if (dateToSort === 'created') {
aa = new Date(a.created).getTime()
bb = new Date(b.created).getTime()
}
if (type === 'num') {
aa = Number(a['stats:items'].count)
bb = Number(b['stats:items'].count)
@@ -176,37 +219,73 @@ function sortNum(type: string): void {
isSorted.value = !isSorted.value
userSequences.value = sorted
}
function goToSequence(sequence: SequenceLinkInterface) {
seqId.value = sequence.id
viewerRef.value.viewer.select(seqId.value)
}
function getRelChild(sequences: SequenceLinkInterface[]) {
return sequences.filter((el: SequenceLinkInterface) => el.rel === 'child')
}
onMounted(async () => {
isLoading.value = true
try {
const { data } = await axios.get('api/users/me/catalog')
const relChild = data.links.filter(
(el: LinkInterface) => el.rel === 'child'
)
userSequences.value = relChild
const collectionData = await axios.get('api/users/me/collection')
collectionBbox.value = collectionData.data.extent.spatial.bbox[0]
viewerRef.value.viewer.fitBounds(collectionBbox.value)
const sequences = getRelChild(data.links)
const sequencesCollection = getRelChild(collectionData.data.links)
sequencesCollection.map((el: SequenceLinkInterface) => {
let index = sequences.findIndex(
(elem: SequenceLinkInterface) => elem.id === el.id
)
sequences[index] = el
})
userSequences.value = sequencesCollection
console.log(userSequences.value)
isLoading.value = false
} catch (err) {
isLoading.value = false
console.log(err)
}
})
watchEffect(() => {
if (viewerRef.value && viewerRef.value.viewer) {
viewerRef.value.viewer.addEventListener(
'hover',
(e: { detail: { seqId: string } }) => {
seqId.value = e.detail.seqId
scrollIntoSelected(e.detail.seqId, userSequences.value)
}
)
}
})
</script>
<style lang="scss" scoped>
.entry-page {
padding-right: toRem(8);
padding-left: toRem(8);
padding-top: toRem(11);
min-height: calc(100vh - #{toRem(8)});
display: flex;
height: calc(100vh - #{toRem(8)});
overflow: hidden;
}
.section-viewer {
width: 40%;
height: 100%;
}
.section-sequence {
overflow-y: auto;
width: 60%;
height: 100%;
}
.sequences-title {
@include text(h1);
margin-bottom: toRem(4);
color: var(--blue-dark);
margin-bottom: toRem(5);
margin-top: toRem(3);
margin-left: toRem(3);
}
.sequence-list {
box-shadow: 0px 2px 30px 0px #0000000f;
border-radius: toRem(2);
padding: 0;
}
.sequence-item {
@@ -216,17 +295,9 @@ onMounted(async () => {
justify-content: center;
margin: auto;
background-color: var(--blue-pale);
&:last-child {
border-bottom-right-radius: toRem(2);
border-bottom-left-radius: toRem(2);
.button-item {
border-bottom-right-radius: toRem(2);
border-bottom-left-radius: toRem(2);
}
}
&:first-child {
margin-bottom: toRem(1);
padding: toRem(1) toRem(3);
padding: toRem(1) toRem(2);
border-bottom: toRem(0.1) solid var(--grey);
border-radius: toRem(2) toRem(2) 0rem 0rem;
background-color: var(--white);
@@ -251,6 +322,15 @@ onMounted(async () => {
height: toRem(15);
z-index: 1;
}
.ready {
color: var(--green);
}
.hidden {
color: var(--red-pale);
}
.waiting-for-process {
color: var(--yellow);
}
.thumb-hover {
height: 100%;
}
@@ -270,14 +350,14 @@ onMounted(async () => {
display: flex;
align-items: center;
width: 100%;
padding: toRem(2) toRem(3);
padding: toRem(2);
background-color: transparent;
border: none;
text-decoration: none;
& > * {
padding: toRem(1);
text-align: initial;
width: 31%;
width: calc(31% - #{toRem(4.75)});
color: var(--black);
}
> :first-child {
@@ -288,8 +368,11 @@ onMounted(async () => {
padding: 0;
margin-right: toRem(2);
}
& > :nth-child(3) {
width: toRem(13);
}
& > :nth-child(2) {
color: var(--blue);
color: var(--blue-dark);
}
&:hover {
background-color: var(--blue);
@@ -298,25 +381,39 @@ onMounted(async () => {
}
}
}
.button-item-hover {
background-color: var(--blue);
& > *,
& > :nth-child(2) {
color: var(--white);
}
}
.bi-images {
margin-right: toRem(0.5);
}
.sequence-header-item {
width: 31%;
width: calc(31% - #{toRem(4.75)});
margin-left: toRem(-1);
&:first-child {
margin-right: toRem(2);
}
&:first-child {
width: toRem(6);
}
&:nth-child(3) {
width: toRem(13);
}
}
.no-sequence {
padding-top: toRem(2);
padding-bottom: toRem(4);
margin: auto;
width: fit-content;
text-align: center;
@include text(m-regular);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: auto;
}
.no-sequence-text {
margin-bottom: toRem(4);
@@ -328,12 +425,31 @@ onMounted(async () => {
height: 100%;
margin-top: toRem(20);
}
.ay11-link {
padding: toRem(2);
margin-left: auto;
width: fit-content;
}
@media (max-width: toRem(102.4)) {
.section-viewer {
width: 30%;
}
.section-sequence {
width: 70%;
}
}
@media (max-width: toRem(76.8)) {
.entry-page {
padding-right: toRem(2);
padding-left: toRem(2);
padding-top: toRem(14);
min-height: calc(100vh - #{toRem(11)});
height: 100%;
}
.section-viewer {
display: none;
}
.section-sequence {
width: 100%;
}
.button-item,
.sequence-item:first-child {

View File

@@ -25,7 +25,7 @@
<div class="entry-copy-button">
<Button
:data-test="`button-copy-${i}`"
look="button--white"
look="button--white background-white"
:text="$t('pages.share_pictures.button_copy')"
:icon="
item.copied
@@ -86,27 +86,29 @@ onMounted(async () => {
<style lang="scss" scoped>
.entry-page {
padding-right: toRem(8);
padding-left: toRem(8);
padding-top: toRem(11);
min-height: calc(100vh - #{toRem(8)});
padding: toRem(5);
min-height: calc(100vh - #{toRem(19.82)});
background-color: var(--grey);
}
.settings-title {
@include text(h1);
color: var(--blue-dark);
margin-bottom: toRem(4);
}
.settings-list {
padding-left: 0;
}
.settings-item-title {
font-size: toRem(1.8);
@include text(h2);
color: var(--blue);
}
.settings-item {
font-size: toRem(1.4);
@include text(m-r-regular);
border: toRem(0.1) solid var(--grey);
border-radius: toRem(0.5);
border-radius: toRem(1.4);
padding: toRem(1.5);
margin-bottom: toRem(2);
background-color: var(--white);
}
.item-information {
height: toRem(5);

View File

@@ -1,387 +1,390 @@
<template>
<main class="entry-page">
<section id="sec-1" class="section-upload">
<div class="wrapper-upload">
<div class="wrapper-upload-text">
<h1 class="upload-title">{{ $t('pages.share_pictures.title') }}</h1>
<div class="wrapper-check">
<div class="wrapper-img-icon">
<i class="bi bi-images img-icon"></i>
</div>
<div class="element-check">
<span class="block-check"
><span class="check-border"></span
>{{ $t('pages.share_pictures.photo_type1') }}</span
>
<span class="block-check"
><span class="check-border"></span
>{{ $t('pages.share_pictures.photo_type2') }}</span
>
<span class="block-check"
><span class="check-border"></span
>{{ $t('pages.share_pictures.photo_type3') }}</span
>
<span class="block-check"
><span class="check-border"></span
>{{ $t('pages.share_pictures.photo_type4') }}</span
>
</div>
</div>
<p
v-if="authConf && authConf.license && authConf.license.url"
class="upload-text"
v-html="
$t('pages.share_pictures.description', {
check: checkImg,
licenseUrl: authConf.license.url,
licenseName: authConf.license.id
})
"
<section class="section">
<div class="section-why-text">
<h1 class="main-title">{{ $t('pages.share_pictures.title') }}</h1>
<p>
{{ $t('pages.share_pictures.description') }}
</p>
</div>
<div class="section-why-img">
<img
src="@/assets/images/how-to-share-map.jpg"
:alt="$t('pages.share_pictures.alt_img_map')"
class="img-why"
/>
</div>
</section>
<section class="section section-features">
<ul class="card-list">
<li class="card-item">
<Card
:title="$t('pages.share_pictures.card_photo1')"
:description="$t('pages.share_pictures.card_description1')"
img-src="building.svg"
:img-alt="$t('pages.share_pictures.card_alt_photo1')"
/>
<p class="upload-text">
{{ $t('pages.share_pictures.footer_block') }}
</p>
<div
v-if="
!isLogged && authConf && authConf.auth && authConf.auth.enabled
"
class="wrapper-account"
>
<h4 class="account-subtitle">
{{ $t('pages.share_pictures.sub_title') }}
</h4>
<div class="entry-link">
<Link
:text="$t('pages.share_pictures.user_account_button')"
type="external"
look="button button--blue"
:path-external="
getAuthRoute('auth/login', 'partager-des-photos')
"
/>
</div>
</div>
</div>
<div class="entry-image">
<div class="image">
<img
src="@/assets/images/upload.png"
:alt="$t('pages.share_pictures.alt_img_upload')"
/>
</div>
</div>
</div>
</li>
<li class="card-item">
<Card
:title="$t('pages.share_pictures.card_photo2')"
:description="$t('pages.share_pictures.card_description2')"
img-src="360.svg"
:img-alt="$t('pages.share_pictures.card_alt_photo2')"
/>
</li>
<li class="card-item">
<Card
:title="$t('pages.share_pictures.card_photo3')"
:description="$t('pages.share_pictures.card_description3')"
img-src="map-pointer.svg"
:img-alt="$t('pages.share_pictures.card_alt_photo3')"
/>
</li>
<li class="card-item">
<Card
:title="$t('pages.share_pictures.card_photo4')"
:description="$t('pages.share_pictures.card_description4')"
img-src="pointer.svg"
:img-alt="$t('pages.share_pictures.card_alt_photo4')"
/>
</li>
</ul>
</section>
<div class="entry-button-down">
<Link
:href="hrefSection"
type="external"
:icon="icon"
look="button--rounded"
@trigger="triggerHref"
/>
<div class="wrapper-section">
<section class="section">
<h2 class="subtitle">
{{ $t('pages.share_pictures.upload_subtitle') }}
</h2>
<div class="wrapper-illustration">
<img
src="@/assets/images/upload-illustration.svg"
:alt="$t('pages.share_pictures.upload_illustration_alt')"
/>
</div>
<p>{{ $t('pages.share_pictures.upload_description') }}</p>
<div class="upload-button">
<Link
:text="$t('pages.share_pictures.upload_button')"
:route="{ name: 'upload-pictures' }"
look="button button--blue"
/>
</div>
</section>
<section class="section">
<h2 class="subtitle">
{{ $t('pages.share_pictures.command_line_subtitle') }}
</h2>
<Terminal
:text-upload="terminalText"
:text-install="$t('pages.share_pictures.terminal_install')"
/>
<p
class="upload-text"
v-html="$t('pages.share_pictures.description_terminal')"
></p>
</section>
</div>
<section id="sec-2" class="section-upload">
<div class="wrapper-upload">
<div class="entry-terminal">
<div class="terminal">
<Terminal
:text-upload="terminalText"
:text-install="terminalTextInstall"
/>
</div>
<div class="wrapper-section">
<section class="section">
<h2 class="subtitle">
{{ $t('pages.share_pictures.information_subtitle') }}
</h2>
<div class="icon-block">
<img
src="@/assets/images/icon/check-green.svg"
alt=""
class="icon-block-img"
/>
<span>{{ $t('pages.share_pictures.information_text1') }}</span>
</div>
<div class="wrapper-upload-text">
<h2 class="upload-title">
{{ $t('pages.share_pictures.title_terminal') }}
</h2>
<p
class="upload-text"
v-html="$t('pages.share_pictures.description_terminal')"
></p>
<div
v-if="authConf && authConf.license && authConf.license.url"
class="upload-text grey"
>
<p>
{{
$t('pages.share_pictures.footer_description_terminal', {
word: 'la license'
})
}}
</p>
<License
v-if="authConf && authConf.license && authConf.license.url"
:url="authConf.license.url"
:text="authConf.license.id"
>
<img
src="@/assets/images/icon/check-green.svg"
alt=""
class="icon-block-img"
/>
</License>
<div class="icon-block">
<img
src="@/assets/images/icon/check-green.svg"
alt=""
class="icon-block-img"
/>
<span>{{ $t('pages.share_pictures.information_text3') }}</span>
</div>
<div class="entry-information-card">
<InformationCard
:title="$t('pages.share_pictures.information_about_title')"
:text="$t('pages.share_pictures.information_about_description')"
look="blue"
/>
</div>
</section>
<section class="section">
<h3 class="about-subtitle">
{{ $t('pages.share_pictures.doc_subtitle') }}
</h3>
<p class="doc-description">
{{ $t('pages.share_pictures.doc_description') }}
</p>
<div class="button-block">
<div class="doc-button">
<Link
:href="authConf.license.url"
:text="authConf.license.id"
target="_blank"
:text="$t('pages.share_pictures.doc_button')"
type="external"
look="link--grey"
@trigger="triggerHref"
path-external="https://gitlab.com/geovisio/cli"
look="button button--white-blue"
/>
</div>
<div class="wrapper-account">
<h4 class="account-subtitle">
{{ $t('pages.share_pictures.cli_title') }}
</h4>
<div class="entry-link">
<Link
:text="$t('pages.share_pictures.button')"
type="external"
look="button button--blue"
path-external="https://gitlab.com/geovisio/cli"
/>
</div>
<div class="wrapper-doc-illustration">
<img
src="@/assets/images/doc-illustration.png"
:alt="$t('pages.share_pictures.doc_illustration_alt')"
class="doc-illustration"
/>
</div>
</div>
</div>
</section>
</section>
</div>
</main>
</template>
<script lang="ts" setup>
import Link from '@/components/Link.vue'
import Terminal from '@/components/Terminal.vue'
import { useCookies } from 'vue3-cookies'
import { computed, ref } from 'vue'
import Card from '@/components/share-pictures/Card.vue'
import InformationCard from '@/components/InformationCard.vue'
import License from '@/components/License.vue'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router'
import { getAuthRoute } from '@/utils/auth'
import authConfig from '../composables/auth'
const { cookies } = useCookies()
const { t } = useI18n()
const { authConf } = authConfig()
const route = useRoute()
let hrefSection = ref<string>('#sec-2')
let icon = ref<string>('bi bi-chevron-down')
const checkImg =
"<span style='background:white; padding: 5px 0.0525px;border-radius:50%; font-size:8px;'>✔</span>"
const isLogged = computed((): boolean => !!cookies.get('user_id'))
const terminalText = computed((): string => {
const url = import.meta.env.VITE_API_URL
? import.meta.env.VITE_API_URL
: 'https://panoramax.ign.fr/'
return t('pages.share_pictures.terminal_text', { url })
})
const terminalTextInstall = computed((): string =>
t('pages.share_pictures.terminal_install')
)
function triggerHref(): void {
icon.value =
route.hash === '#sec-2' ? 'bi bi-chevron-down' : 'bi bi-chevron-up'
hrefSection.value = route.hash === '#sec-2' ? '#sec-1' : '#sec-2'
}
</script>
<style lang="scss" scoped>
.upload-title {
@include text(h1);
h1,
h2,
h3,
p,
ul {
margin: 0;
padding: 0;
}
.account-subtitle {
@include text(h4);
.entry-page {
background-color: var(--grey);
color: var(--grey-dark);
padding: toRem(2) toRem(5) toRem(5);
@include text(m-r-regular);
}
.entry-link {
margin-top: toRem(1);
}
.upload-text {
@include text(m-regular);
margin-top: toRem(5);
}
.wrapper-check {
position: relative;
width: fit-content;
padding: toRem(3);
.section {
display: flex;
background-color: var(--white);
border-radius: toRem(1.4);
font-size: toRem(1.6);
margin-top: toRem(8);
border-radius: toRem(2.2);
padding: toRem(4);
margin-bottom: toRem(2);
}
.wrapper-img-icon {
background-color: var(--black);
border-radius: 50%;
position: absolute;
height: toRem(5.5);
width: toRem(5.5);
.wrapper-section {
display: flex;
justify-content: center;
align-items: center;
font-size: toRem(3);
top: toRem(-3);
left: 50%;
transform: translate(-50%);
}
.img-icon {
color: var(--white);
}
.element-check {
display: flex;
flex-direction: column;
margin-top: toRem(3);
}
.block-check {
margin-bottom: toRem(1);
display: flex;
}
.check-border {
display: flex;
justify-content: center;
align-items: center;
width: toRem(2.2);
height: toRem(2.2);
border-radius: 50%;
font-size: toRem(0.8);
background: var(--white);
border: toRem(0.1) solid var(--black);
margin-right: toRem(0.5);
}
.block-check:last-child {
margin-bottom: 0;
}
.section-upload {
height: 100%;
padding-right: toRem(2);
padding-left: toRem(2);
display: flex;
flex-direction: column;
justify-content: center;
min-height: 80vh;
}
.section-upload:first-child {
background-color: rgba(236, 236, 236, 0.5);
}
.wrapper-upload {
display: flex;
align-items: initial;
justify-content: center;
}
.wrapper-upload-text {
width: 40%;
white-space: pre-wrap;
}
.grey {
display: flex;
align-items: center;
flex-wrap: wrap;
color: var(--grey-semi-dark);
p {
margin-bottom: 0;
margin-right: toRem(0.5);
.section {
width: 50%;
flex-direction: column;
}
.section:first-child {
margin-right: toRem(2);
}
}
.wrapper-account {
.section-why-text {
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: space-between;
margin-top: toRem(3);
padding-top: toRem(1);
border-top: toRem(0.1) solid #e6e6e6;
flex-direction: column;
margin-right: toRem(2);
width: 60%;
}
.section-why-img {
display: flex;
justify-content: center;
width: 40%;
}
.img-why {
object-fit: contain;
}
.main-title {
@include text(h1);
color: var(--blue-dark);
margin-bottom: toRem(2);
}
.card-list {
display: flex;
}
.card-item {
width: 25%;
&:nth-child(2) {
margin-right: toRem(4);
margin-left: toRem(4);
}
&:nth-child(4) {
margin-left: toRem(4);
}
}
.wrapper-illustration {
display: flex;
justify-content: center;
background-color: var(--blue-pale);
border: toRem(0.1) dashed var(--blue);
border-radius: toRem(2.2);
padding: toRem(4);
margin-bottom: toRem(3);
}
.subtitle {
@include text(h2);
color: var(--blue-dark);
margin-bottom: toRem(2);
}
.upload-button {
display: flex;
margin-top: toRem(4);
}
.upload-text {
white-space: pre-wrap;
@include text(m-r-regular);
margin-top: toRem(5);
}
.entry-information-card {
margin-top: toRem(2);
}
.icon-block-img {
margin-right: toRem(0.5);
}
.about-subtitle {
@include text(h2);
color: var(--blue-dark);
}
.doc-description {
margin-top: toRem(3);
}
.image {
background-color: var(--white);
border-radius: toRem(1);
padding: toRem(1);
border: 1px solid var(--black);
width: 75%;
height: fit-content;
}
.entry-image {
.button-block {
display: flex;
justify-content: center;
width: 35%;
overflow: hidden;
margin-left: toRem(6);
align-items: center;
justify-content: space-between;
height: 100%;
flex-wrap: wrap-reverse;
}
.entry-terminal {
margin-left: 0;
margin-right: toRem(6);
.doc-button {
margin-right: toRem(2);
width: fit-content;
}
.entry-image img {
width: 100%;
border-radius: toRem(1);
.wrapper-doc-illustration {
display: flex;
justify-content: flex-end;
}
.entry-button-down {
z-index: 1;
position: fixed;
right: toRem(2);
bottom: calc(20vh - #{toRem(10.5)});
.doc-illustration {
width: fit-content;
}
@media (max-width: toRem(102.4)) {
.section-upload {
height: initial;
.card-list {
flex-wrap: wrap;
}
.wrapper-upload {
.card-item {
width: calc(50% - #{toRem(2)});
&:nth-child(2),
&:nth-child(1) {
margin-right: toRem(0);
margin-bottom: toRem(4);
}
}
.button-block {
flex-direction: column-reverse;
padding-top: toRem(6);
padding-bottom: toRem(6);
justify-content: center;
}
.wrapper-upload-text {
.doc-button {
margin-top: toRem(2);
margin-right: 0;
}
}
@media (max-width: toRem(84.8)) {
.section {
flex-direction: column;
}
.section-why-text {
width: 100%;
margin-right: 0;
}
.entry-image {
display: none;
}
.entry-terminal {
.section-why-img {
margin-top: toRem(2);
width: 100%;
justify-content: initial;
}
.terminal {
width: 100%;
margin-top: toRem(4);
}
}
@media (max-width: toRem(76.8)) {
.entry-page {
padding-top: toRem(11);
padding-top: toRem(15);
}
.entry-image {
width: 60%;
margin-right: 0;
margin-left: 0;
}
.entry-terminal {
.card-item {
&:nth-child(1),
&:nth-child(2),
&:nth-child(3),
&:nth-child(4) {
margin: 0 0 toRem(4);
}
width: 100%;
}
.wrapper-upload-text {
margin-left: 0;
margin-right: 0;
.wrapper-card {
align-items: center;
}
.wrapper-section {
flex-direction: column;
.section {
width: 100%;
}
}
.doc-button {
margin-top: toRem(2);
}
}
@media (max-width: toRem(50)) {
.entry-page {
min-height: calc(100vh - #{toRem(11)});
padding-top: toRem(11);
.entry-page,
.section {
padding-right: toRem(2);
padding-left: toRem(2);
}
.entry-image {
width: 100%;
padding-right: 0;
padding-left: 0;
.section {
padding-top: toRem(2);
padding-bottom: toRem(2);
}
.image {
.img-why {
width: 100%;
}
.wrapper-upload-text {
margin-right: 0;
padding-right: 0;
padding-left: 0;
.card-item:last-child {
margin-bottom: 0;
}
.upload-text {
margin-bottom: toRem(3);
.wrapper-illustration {
img {
height: toRem(10);
}
}
.wrapper-account {
padding-top: toRem(3);
flex-direction: column;
.upload-button {
margin-top: toRem(2);
width: 100%;
}
.account-subtitle {
margin-bottom: toRem(2);
.doc-button {
width: 100%;
}
.entry-button-down {
display: none;
.doc-description {
margin-top: toRem(1.5);
}
.section-why-img {
height: toRem(14);
}
}
</style>

View File

@@ -1,49 +1,84 @@
<template>
<main class="entry-page">
<section class="upload-section">
<h1 class="settings-title">{{ $t('pages.upload.title') }}</h1>
<form v-if="!isLoading" @submit.prevent="uploadPicture">
<InputUpload
:text="$t('pages.upload.input_label')"
:text-second-part="$t('pages.upload.import_word')"
:text-picture-type="$t('pages.upload.import_type')"
accept="image/jpeg"
data-test="input-add-pictures"
@trigger="addPictures"
/>
<div class="footer-form">
<span v-if="fileUploaded" class="number-file-text">{{
fileUploaded
}}</span>
<span v-else class="number-file-text">{{
t('pages.upload.no_uploaded_files')
}}</span>
<section class="section">
<InformationCard
v-if="informationCardDisplayed"
:text="$t('pages.upload.description')"
:title="$t('pages.upload.title')"
>
<template v-slot:cross>
<Button
:text="$t('pages.upload.button_text')"
:disabled="!pictures || pictures.length < 1"
type="submit"
data-test="button-upload"
look="button button--blue"
icon="bi bi-x-lg"
look="no-text"
@trigger="informationCardDisplayed = false"
/>
</div>
</form>
<UploadLoader
v-else
:load-percentage="loadPercentage"
:load-text-size="loadTextSize"
:is-loaded="isLoaded"
:uploaded-sequences="uploadedSequences"
:pictures-count="picturesCount"
@triggerNewUpload="triggerNewUpload"
/>
</template>
<template v-slot:button>
<div class="button-know-more">
<Link
:text="$t('pages.upload.know_more_button')"
:route="{ name: 'why-contribute' }"
look="button button--white-blue"
class="entry-button"
/>
</div>
</template>
</InformationCard>
</section>
<ImportedSection
v-for="(sequence, i) in uploadedSequences"
:index="i"
:sequence="sequence"
:pictures-count="picturesCount"
:upload-errors="sequence.picturesOnError"
:upload-pictures="sequence.pictures"
<div class="wrapper-section">
<section class="sub-section">
<h2 class="subtitle">{{ $t('pages.upload.subtitle_import') }}</h2>
<p class="import-text">{{ $t('pages.upload.text_import') }}</p>
<License
v-if="authConf && authConf.license && authConf.license.url"
:url="authConf.license.url"
:text="authConf.license.id"
/>
<form>
<div class="wrapper-form">
<InputUpload
v-if="inputIsDisplayed"
:text="$t('pages.upload.input_label')"
:text-second-part="$t('pages.upload.import_word')"
:text-picture-type="$t('pages.upload.import_type')"
accept="image/jpeg"
data-displayModal="input-add-pictures"
@trigger="addPictures"
/>
<div v-else class="wrapper-uploading">
<img
src="@/assets/images/uploading-person.svg"
alt=""
class="uploading-img"
/>
<span>{{ $t('pages.upload.uploading_process') }}</span>
<span class="loader-text-warning">{{
$t('pages.upload.leave_message')
}}</span>
</div>
</div>
</form>
</section>
<section class="sub-section">
<h2 class="subtitle">{{ $t('pages.upload.subtitle_process') }}</h2>
<UploadLoader
v-if="isLoading"
:load-percentage="loadPercentage"
:is-loaded="isLoaded"
:uploaded-sequence="uploadedSequence"
:pictures-count="picturesCount"
@triggerModal="displayModal"
/>
<div v-else class="wrapper-no-img">
<img src="@/assets/images/no-uploaded-img.svg" alt="" />
<p>{{ $t('pages.upload.no_img_text') }}</p>
</div>
</section>
</div>
<Modal
v-if="uploadedSequence && uploadedSequence.picturesOnError"
ref="modal"
:upload-errors="uploadedSequence.picturesOnError"
/>
</main>
</template>
@@ -54,30 +89,32 @@ import { onBeforeRouteLeave } from 'vue-router'
import { useI18n } from 'vue-i18n'
import InputUpload from '@/components/InputUpload.vue'
import Button from '@/components/Button.vue'
import ImportedSection from '@/components/upload/ImportedSection.vue'
import Modal from '@/components/Modal.vue'
import InformationCard from '@/components/InformationCard.vue'
import UploadLoader from '@/components/upload/UploadLoader.vue'
import type { sequenceInterface } from './interfaces/UploadPicturesView'
import License from '@/components/License.vue'
import type { SequenceInterface } from './interfaces/UploadPicturesView'
import { formatDate } from '@/utils/dates'
import {
createAPictureToASequence,
createASequence
} from '@/views/utils/upload/request'
import {
formatPictureSize,
formatTextSize,
sortByName
} from '@/views/utils/upload/index'
import { sortByName } from '@/views/utils/upload/index'
import authConfig from '../composables/auth'
import Link from '@/components/Link.vue'
const { authConf } = authConfig()
const { t } = useI18n()
let pictures = ref<File[] | []>([])
let picturesCount = ref<number>(0)
let isLoading = ref<boolean>(false)
let isLoaded = ref<boolean>(false)
let uploadingPictures = ref<FileList | []>([])
let uploadedSequences = ref<sequenceInterface[] | []>([])
let informationCardDisplayed = ref<boolean>(true)
let uploadedSequence = ref<SequenceInterface | null>(null)
let picturesUploadingSize = ref<number>(0)
let picturesToUploadSize = ref<number>(0)
let loadPercentage = ref<string>('0%')
let loadTextSize = ref<string>('0 Mo')
let modal = ref()
watch(isLoading, () => {
if (isLoading.value) {
@@ -90,7 +127,6 @@ watch(isLoading, () => {
window.onbeforeunload = null
}
})
onUnmounted(() => {
window.onbeforeunload = null
})
@@ -102,9 +138,12 @@ onBeforeRouteLeave((to, from, next) => {
}
next()
})
const fileUploaded = computed<string>(() => {
return t('pages.upload.uploaded_files', { count: picturesCount.value })
})
const inputIsDisplayed = computed<boolean | null>(
() =>
!isLoading.value ||
isLoaded.value ||
(uploadedSequence.value && !uploadedSequence.value.pictures)
)
function picturesToUploadSizeText(): void {
let fullSize = 0
@@ -112,7 +151,6 @@ function picturesToUploadSizeText(): void {
fullSize += pictures.value[i].size
}
picturesToUploadSize.value = fullSize
loadTextSize.value = formatTextSize(fullSize, formatPictureSize(fullSize))
}
function calcPercentage(): void {
if (picturesUploadingSize.value && picturesToUploadSize.value) {
@@ -123,9 +161,8 @@ function calcPercentage(): void {
}
}
function triggerNewUpload(): void {
isLoading.value = false
picturesCount.value = 0
function displayModal(): void {
if (modal.value) modal.value.show()
}
function addPictures(value: FileList): void {
const files = sortByName([].slice.call(value))
@@ -134,14 +171,7 @@ function addPictures(value: FileList): void {
picturesUploadingSize.value = 0
picturesToUploadSize.value = 0
loadPercentage.value = '0%'
loadTextSize.value = '0 Mo'
}
function setPictureSizeValue(sequence: sequenceInterface, size: number): void {
picturesUploadingSize.value = picturesUploadingSize.value + size
sequence.pictureSize = formatTextSize(
picturesUploadingSize.value,
formatPictureSize(picturesUploadingSize.value)
)
uploadPicture()
}
async function uploadPicture(): Promise<void> {
if (!pictures.value || !pictures.value.length) {
@@ -150,6 +180,7 @@ async function uploadPicture(): Promise<void> {
isLoaded.value = false
isLoading.value = true
picturesToUploadSizeText()
uploadedSequence.value = null
const picturesToUpload = [...pictures.value]
const sequenceTitle = `${t('pages.upload.sequence_title')}${formatDate(
@@ -157,7 +188,7 @@ async function uploadPicture(): Promise<void> {
'Do MMMM YYYY, hh:mm:ss'
)}`
const { data } = await createASequence(sequenceTitle)
const sequence: sequenceInterface = {
uploadedSequence.value = {
title: sequenceTitle,
id: data.id,
pictures: [],
@@ -165,7 +196,6 @@ async function uploadPicture(): Promise<void> {
pictureCount: pictures.value.length,
pictureSize: ''
}
uploadedSequences.value = [sequence, ...uploadedSequences.value]
let i = 0
for (let el of picturesToUpload) {
const body = new FormData()
@@ -175,32 +205,34 @@ async function uploadPicture(): Promise<void> {
try {
const pictureUploaded = await createAPictureToASequence(data.id, body)
const pictures = { ...pictureUploaded.data, name: el.name }
setPictureSizeValue(sequence, el.size)
sequence.pictures = [...sequence.pictures, pictures]
const index = uploadedSequences.value.findIndex(
(item: sequenceInterface) => item.id === data.id
)
uploadedSequences.value.splice(index, 1)
uploadedSequences.value = [sequence, ...uploadedSequences.value]
picturesUploadingSize.value = picturesUploadingSize.value + el.size
uploadedSequence.value.pictures = [
...uploadedSequence.value.pictures,
pictures
]
calcPercentage()
} catch (err: any) {
setPictureSizeValue(sequence, el.size)
picturesUploadingSize.value = picturesUploadingSize.value + el.size
const picturesOnError = {
message: err.response.data.message,
name: el.name
}
sequence.picturesOnError = [...sequence.picturesOnError, picturesOnError]
uploadedSequence.value.picturesOnError = [
...uploadedSequence.value.picturesOnError,
picturesOnError
]
calcPercentage()
}
}
isLoaded.value = true
uploadingPictures.value = []
pictures.value = []
picturesCount.value = 0
}
</script>
<style scoped lang="scss">
ul {
ul,
h3 {
padding-left: 0;
margin-bottom: 0;
}
@@ -209,59 +241,98 @@ ul {
flex-direction: column;
justify-content: center;
align-items: center;
min-height: calc(100vh - #{toRem(27.42)});
min-height: calc(100vh - #{toRem(13.82)});
background-color: var(--grey);
padding: toRem(2) toRem(5) toRem(5);
color: var(--grey-dark);
}
.upload-section {
width: 80%;
padding: toRem(4);
margin-top: toRem(6);
margin-bottom: toRem(4);
box-shadow: 0px 6.45694px 8.60925px rgba(0, 0, 0, 0.05);
.section {
width: 100%;
}
.settings-title {
.button-know-more {
width: toRem(15.5);
margin-right: toRem(3);
margin-bottom: toRem(1);
}
.wrapper-section {
display: flex;
width: 100%;
margin-top: toRem(2);
}
.sub-section {
min-height: toRem(48);
width: 50%;
background-color: var(--white);
padding: toRem(2);
border-radius: toRem(1.5);
&:first-child {
margin-right: toRem(2);
}
}
.subtitle {
@include text(h3);
color: var(--blue-dark);
}
.import-text {
@include text(m-r-regular);
}
.wrapper-form {
border: toRem(0.1) dashed var(--blue);
background-color: var(--blue-pale);
border-radius: toRem(1.5);
padding: toRem(2);
}
.wrapper-uploading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.uploading-img {
height: toRem(20);
}
.loader-text-warning {
text-align: center;
@include text(h1);
margin-bottom: toRem(4);
@include text(s-r-regular);
color: var(--orange);
margin-top: toRem(1);
width: toRem(31);
}
.footer-form {
.wrapper-no-img {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-top: toRem(3);
}
.number-file-text {
margin-bottom: toRem(2);
color: var(--blue-dark);
@include text(s-regular);
}
::-webkit-scrollbar {
width: toRem(2);
}
::-webkit-scrollbar-track {
background: var(--grey-pale);
}
::-webkit-scrollbar-thumb {
background: var(--blue);
border-radius: toRem(5);
}
@media (max-width: toRem(76.8)) {
.entry-page {
overflow-x: hidden;
padding-top: toRem(15);
}
.information-section {
flex-direction: column;
}
}
@media (max-width: toRem(50)) {
.upload-section {
margin-top: toRem(15);
width: 100%;
.entry-page {
padding-right: toRem(2);
padding-left: toRem(2);
}
.information-section {
.wrapper-section {
flex-direction: column;
}
.sub-section {
width: 100%;
margin-bottom: toRem(2);
&:first-child {
margin-right: 0;
}
}
.wrapper-no-img {
margin-top: toRem(6);
}
}
@media (max-width: toRem(50)) {
.sub-section {
min-height: initial;
}
.uploading-img {
height: toRem(10);
}
}
</style>

View File

@@ -25,6 +25,7 @@ export interface UserSequenceInterface {
camera: string
cameraModel: string
status: string
providers: [{ name: string; roles: [string] }]
extent: { temporal: { interval: [Date[]] }; spatial: { bbox: string[] } }
}

View File

@@ -1,16 +1,18 @@
export interface LinkInterface {
export interface SequenceLinkInterface {
id: string
href: string
rel: string
title: string
type: string
created: Date
extent: { temporal: { interval: [Date[]] } }
['stats:items']: { count: number }
['geovisio:status']: string
}
export interface ExtentLinkInterface {
export interface ExtentSequenceLinkInterface {
extent: { temporal: { interval: [Date[]] } }
['stats:items']: { count: number }
title: string
created: Date
}

View File

@@ -1,4 +1,4 @@
export interface sequenceInterface {
export interface SequenceInterface {
title: string
id: string
pictures: any[]

View File

@@ -1,4 +1,4 @@
export interface OptionalViewerMapInterface {
export interface OptionalViewerInterface {
fetchOptions?: {
credentials: string
}
@@ -8,7 +8,7 @@ export interface OptionalViewerMapInterface {
}
}
export interface ViewerMapInterface extends OptionalViewerMapInterface {
export interface ViewerInterface extends OptionalViewerInterface {
map: {
startWide: boolean
style?: object | string
@@ -16,4 +16,5 @@ export interface ViewerMapInterface extends OptionalViewerMapInterface {
zoom?: number
center?: number[]
}
bounds?: number[]
}

View File

@@ -7,14 +7,11 @@ function imageStatus(imageStatus: string, sequenceStatus: string): string {
if (sequenceStatus === 'hidden') return sequenceStatus
return imageStatus
}
function scrollIntoSelected(
id: string,
userPhotos: ResponseUserPhotoInterface[]
): void {
const itemPosition = userPhotos.map((el) => el.id).indexOf(id)
const elementTarget = document.querySelector(`#photo${itemPosition}`)
if (elementTarget) elementTarget.scrollIntoView()
//TODO REMOVE ANY
function scrollIntoSelected(id: string, userPhotos: any): void {
const itemPosition = userPhotos.map((el: any) => el.id).indexOf(id)
const elementTarget = document.querySelector(`#el-list${itemPosition}`)
if (elementTarget) elementTarget.scrollIntoView({ behavior: 'smooth' })
}
function photoToDeleteOrPatchSelected(

View File

@@ -1,10 +1,3 @@
function formatPictureSize(size: number): number {
return Math.floor(Math.log(size) / Math.log(1024))
}
function formatTextSize(size: number, i: number): string {
const sizes = ['0', 'Ko', 'Mo', 'Go', 'To', 'Po', 'Eo', 'Zo', 'o']
return `${parseFloat((size / Math.pow(1024, i)).toFixed(2))} ${sizes[i]}`
}
function sortByName(fileList: File[]): File[] {
return fileList.sort((a: File, b: File) =>
a.name.localeCompare(b.name, navigator.languages[0] || navigator.language, {
@@ -13,4 +6,4 @@ function sortByName(fileList: File[]): File[] {
})
)
}
export { formatPictureSize, formatTextSize, sortByName }
export { sortByName }

979
yarn.lock

File diff suppressed because it is too large Load Diff