landing desktop

This commit is contained in:
2026-06-12 20:16:14 +03:30
parent 820e80ac16
commit 5eec309b54
89 changed files with 4343 additions and 2309 deletions
+41
View File
@@ -0,0 +1,41 @@
import { defineStore } from 'pinia';
import { computed, ref } from 'vue';
import { fetchPlatformSettings } from '@/api/platform-settings';
import { uploadUrl } from '@/utils/media';
const DEFAULT_LOGIN_HERO = '/landing/hero-car-wash.jpg';
export const usePlatformSettingsStore = defineStore('platformSettings', () => {
const loginHeroImageUrl = ref<string | null>(null);
const loaded = ref(false);
const loading = ref(false);
const loginHeroSrc = computed(
() => uploadUrl(loginHeroImageUrl.value) || DEFAULT_LOGIN_HERO,
);
async function load(force = false) {
if (loaded.value && !force) return;
if (loading.value) return;
loading.value = true;
try {
const data = await fetchPlatformSettings();
loginHeroImageUrl.value = data.loginHeroImageUrl;
loaded.value = true;
} catch {
loginHeroImageUrl.value = null;
loaded.value = true;
} finally {
loading.value = false;
}
}
return {
loginHeroImageUrl,
loginHeroSrc,
loaded,
loading,
load,
};
});
+20
View File
@@ -0,0 +1,20 @@
import { defineStore } from 'pinia';
import { ref } from 'vue';
export const useProfileModalStore = defineStore('profileModal', () => {
const isOpen = ref(false);
function open() {
isOpen.value = true;
}
function close() {
isOpen.value = false;
}
function toggle() {
isOpen.value = !isOpen.value;
}
return { isOpen, open, close, toggle };
});
+75
View File
@@ -0,0 +1,75 @@
import { defineStore } from 'pinia';
import { computed, ref } from 'vue';
import { fetchBusinessCategories } from '@/api/business-categories';
import { fetchBusiness, fetchBusinesses } from '@/api/businesses';
import type { Business } from '@/api/types';
import { MONTIME_BRAND, NIVASH_BRAND, type SiteBrand } from '@/constants/site-branding';
export const useTenantStore = defineStore('tenant', () => {
const loaded = ref(false);
const loading = ref(false);
const isSingleBusiness = ref(false);
const singleBusiness = ref<Business | null>(null);
const brand = computed<SiteBrand>(() => {
const base = isSingleBusiness.value ? NIVASH_BRAND : MONTIME_BRAND;
if (isSingleBusiness.value && singleBusiness.value) {
return {
...base,
name: singleBusiness.value.title,
shortName: singleBusiness.value.title,
copyrightName: singleBusiness.value.title,
aboutText:
singleBusiness.value.description?.trim() || base.aboutText,
};
}
return base;
});
const singleBusinessId = computed(() => singleBusiness.value?.id ?? null);
function syncSingleBusiness(business: Business) {
if (!isSingleBusiness.value) return;
singleBusiness.value = business;
}
async function bootstrap() {
if (loaded.value || loading.value) return;
loading.value = true;
try {
const [categories, businesses] = await Promise.all([
fetchBusinessCategories(),
fetchBusinesses({ isActive: true }),
]);
const activeCategories = categories.filter((c) => c.isActive);
isSingleBusiness.value =
activeCategories.length === 1 && businesses.length === 1;
if (isSingleBusiness.value) {
singleBusiness.value = await fetchBusiness(businesses[0].id);
} else {
singleBusiness.value = null;
}
} catch {
isSingleBusiness.value = false;
singleBusiness.value = null;
} finally {
loading.value = false;
loaded.value = true;
}
}
return {
loaded,
loading,
isSingleBusiness,
singleBusiness,
singleBusinessId,
brand,
bootstrap,
syncSingleBusiness,
};
});