create landing page for boursemes
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
import { inject, provide, type InjectionKey } from 'vue'
|
||||
import { useConfigStore } from '@/store/configStore'
|
||||
|
||||
export interface AboutUsPageContext {
|
||||
config: ReturnType<typeof useConfigStore>
|
||||
}
|
||||
|
||||
export const ABOUT_US_PAGE_CONTEXT_KEY: InjectionKey<AboutUsPageContext> = Symbol('aboutUsPageContext')
|
||||
|
||||
export function useAboutUsPage() {
|
||||
const config = useConfigStore()
|
||||
|
||||
const context: AboutUsPageContext = {
|
||||
config,
|
||||
}
|
||||
|
||||
provide(ABOUT_US_PAGE_CONTEXT_KEY, context)
|
||||
return context
|
||||
}
|
||||
|
||||
export function useAboutUsPageContext() {
|
||||
const context = inject(ABOUT_US_PAGE_CONTEXT_KEY)
|
||||
if (!context) {
|
||||
throw new Error('useAboutUsPageContext must be used within a page that calls useAboutUsPage()')
|
||||
}
|
||||
return context
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div class="about-us-page-root">
|
||||
<DesktopAboutUsView />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useAboutUsPage } from './composables/useAboutUsPage'
|
||||
import DesktopAboutUsView from './desktop/DesktopAboutUsView.vue'
|
||||
|
||||
useAboutUsPage()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.about-us-page-root {
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #f4f5f7;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
/*
|
||||
* Mobile shell locks html/body overflow. Scroll the landing inside the page root.
|
||||
* Desktop must NOT use overflow:auto here — a full-height auto container with
|
||||
* overscroll-behavior:contain steals wheel events and blocks document scroll.
|
||||
*/
|
||||
html:not(.app-layout--desktop) .app-main > .about-us-page-root {
|
||||
min-height: 0;
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overscroll-behavior-y: contain;
|
||||
}
|
||||
|
||||
html.dlanding-menu-open .about-us-page-root {
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,206 @@
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { getAllPrices } from '@/api/home'
|
||||
import { getProductsCatalog, getProductsCatalogRef } from '@/composables/useProductsCatalog'
|
||||
import { getTradeBuyPrice, getTradeSellPrice } from '@/utils/price'
|
||||
|
||||
export type ChartMetalType = 'katod' | 'maftol' | 'shamsh'
|
||||
|
||||
type ChartPoint = [number, number]
|
||||
|
||||
/**
|
||||
* مارکآپ ثابت روی قیمت بورس کالا برای نمودار:
|
||||
* کاتد +۳٪ ، مفتول +۶٪ ، شمش +۱۲٪
|
||||
*/
|
||||
export const CHART_METAL_MARKUP_RATIO: Record<ChartMetalType, number> = {
|
||||
katod: 0.03,
|
||||
maftol: 0.06,
|
||||
shamsh: 0.12,
|
||||
}
|
||||
|
||||
/** Module-level chart state — one dataset shared by mobile and desktop PriceChart instances. */
|
||||
const priceChartSeries = ref<{ name: string; data: ChartPoint[] }[]>([
|
||||
{ name: 'قیمت', data: [] },
|
||||
])
|
||||
const rawChartPoints = ref<ChartPoint[]>([])
|
||||
const chartSelection = ref('DAILY')
|
||||
const chartLoading = ref(false)
|
||||
const selectedChartMetal = ref<ChartMetalType>('katod')
|
||||
const catalogProducts = getProductsCatalogRef()
|
||||
|
||||
const maftolChartRatio = computed(() => CHART_METAL_MARKUP_RATIO.maftol)
|
||||
const shamshChartRatio = computed(() => CHART_METAL_MARKUP_RATIO.shamsh)
|
||||
|
||||
const selectedMetalChartRatio = computed(
|
||||
() => CHART_METAL_MARKUP_RATIO[selectedChartMetal.value],
|
||||
)
|
||||
|
||||
let chartFetchPromise: Promise<void> | null = null
|
||||
let chartInitialized = false
|
||||
let metalOffsetPromise: Promise<void> | null = null
|
||||
let metalOffsetLoaded = false
|
||||
|
||||
function applyChartRatio(basePrice: number, ratio: number) {
|
||||
if (!ratio) {
|
||||
return basePrice
|
||||
}
|
||||
|
||||
return Math.round(basePrice + basePrice * ratio)
|
||||
}
|
||||
|
||||
/** بالاترین/پایینترین امروز — همان مارکآپ ثابت فلز روی قیمت بورس کالا */
|
||||
export function resolveMetalDayRangePrices(options: {
|
||||
price: { up?: { buy?: number; sell?: number }; buy?: number; sell?: number; price_last?: number } | null | undefined
|
||||
metal: ChartMetalType
|
||||
metalRatio: number
|
||||
}) {
|
||||
const baseHigh = options.price?.up?.buy ?? getTradeBuyPrice(options.price as Parameters<typeof getTradeBuyPrice>[0])
|
||||
const baseLow = options.price?.up?.sell ?? getTradeSellPrice(options.price as Parameters<typeof getTradeSellPrice>[0])
|
||||
const ratio = options.metalRatio || CHART_METAL_MARKUP_RATIO[options.metal]
|
||||
|
||||
return {
|
||||
high: applyChartRatio(baseHigh, ratio),
|
||||
low: applyChartRatio(baseLow, ratio),
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeChartTimestamp(timestamp: number) {
|
||||
return timestamp < 1_000_000_000_000 ? timestamp * 1000 : timestamp
|
||||
}
|
||||
|
||||
function resolvePricesMap(response: unknown): Record<string, Array<{ timestamp: number; value: number }>> | null {
|
||||
if (!response || typeof response !== 'object') {
|
||||
return null
|
||||
}
|
||||
|
||||
const body = response as Record<string, unknown>
|
||||
const nested = body.data
|
||||
|
||||
if (nested && typeof nested === 'object' && 'prices' in nested) {
|
||||
return (nested as { prices: Record<string, Array<{ timestamp: number; value: number }>> }).prices
|
||||
}
|
||||
|
||||
if ('prices' in body) {
|
||||
return body.prices as Record<string, Array<{ timestamp: number; value: number }>>
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function buildChartPoints(items: Array<{ timestamp: number; value: number }>): ChartPoint[] {
|
||||
return items.map((item) => [
|
||||
normalizeChartTimestamp(item.timestamp),
|
||||
item.value - 1,
|
||||
])
|
||||
}
|
||||
|
||||
function syncChartSeries() {
|
||||
const ratio = selectedMetalChartRatio.value
|
||||
priceChartSeries.value[0].data = rawChartPoints.value.map(
|
||||
([timestamp, value]) => [timestamp, applyChartRatio(value, ratio)] as ChartPoint,
|
||||
)
|
||||
}
|
||||
|
||||
watch([selectedChartMetal, maftolChartRatio, shamshChartRatio], () => {
|
||||
syncChartSeries()
|
||||
})
|
||||
|
||||
async function fetchPrices(force = false) {
|
||||
if (!force && chartInitialized && rawChartPoints.value.length > 0) {
|
||||
syncChartSeries()
|
||||
return
|
||||
}
|
||||
|
||||
if (!force && chartFetchPromise) {
|
||||
return chartFetchPromise
|
||||
}
|
||||
|
||||
chartFetchPromise = (async () => {
|
||||
try {
|
||||
chartLoading.value = true
|
||||
const response = await getAllPrices()
|
||||
const data = resolvePricesMap(response)
|
||||
const selectedData = data?.[chartSelection.value] ?? []
|
||||
rawChartPoints.value = buildChartPoints(selectedData)
|
||||
syncChartSeries()
|
||||
chartInitialized = true
|
||||
} catch (error) {
|
||||
console.error('Error fetching prices:', error)
|
||||
} finally {
|
||||
chartLoading.value = false
|
||||
chartFetchPromise = null
|
||||
}
|
||||
})()
|
||||
|
||||
return chartFetchPromise
|
||||
}
|
||||
|
||||
async function loadMetalChartOffsets(force = false) {
|
||||
if (!force && metalOffsetLoaded && catalogProducts.value.length > 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!force && metalOffsetPromise) {
|
||||
return metalOffsetPromise
|
||||
}
|
||||
|
||||
metalOffsetPromise = (async () => {
|
||||
try {
|
||||
await getProductsCatalog(force)
|
||||
syncChartSeries()
|
||||
metalOffsetLoaded = true
|
||||
} catch (error) {
|
||||
console.error('Error loading boursecu chart metal ratios:', error)
|
||||
syncChartSeries()
|
||||
} finally {
|
||||
metalOffsetPromise = null
|
||||
}
|
||||
})()
|
||||
|
||||
return metalOffsetPromise
|
||||
}
|
||||
|
||||
function updateChartData(timeline: string) {
|
||||
chartSelection.value = timeline
|
||||
void fetchPrices(true)
|
||||
}
|
||||
|
||||
function setChartMetal(metal: ChartMetalType) {
|
||||
selectedChartMetal.value = metal
|
||||
syncChartSeries()
|
||||
}
|
||||
|
||||
export function usePriceChart() {
|
||||
return {
|
||||
priceChartSeries,
|
||||
chartSelection,
|
||||
chartLoading,
|
||||
selectedChartMetal,
|
||||
maftolChartRatio,
|
||||
shamshChartRatio,
|
||||
selectedMetalChartRatio,
|
||||
updateChartData,
|
||||
fetchPrices,
|
||||
loadMaftolOffset: loadMetalChartOffsets,
|
||||
loadMetalChartOffsets,
|
||||
setChartMetal,
|
||||
}
|
||||
}
|
||||
|
||||
export function fetchHomeChartPrices(force = false) {
|
||||
return fetchPrices(force)
|
||||
}
|
||||
|
||||
export function loadHomeMaftolOffset(force = false) {
|
||||
return loadMetalChartOffsets(force)
|
||||
}
|
||||
|
||||
export function resetHomePriceChart() {
|
||||
priceChartSeries.value = [{ name: 'قیمت', data: [] }]
|
||||
rawChartPoints.value = []
|
||||
chartSelection.value = 'DAILY'
|
||||
selectedChartMetal.value = 'katod'
|
||||
chartInitialized = false
|
||||
chartFetchPromise = null
|
||||
metalOffsetLoaded = false
|
||||
metalOffsetPromise = null
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<script setup lang="ts">
|
||||
import BasicModal from '@/components/BasicPacks/BasicModal.vue'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import shareAppleIcon from '@/assets/img/share-apple.png'
|
||||
import addToHomeScreenIcon from '@/assets/img/Add-to-homeScreen.png'
|
||||
|
||||
defineProps<{
|
||||
show: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:show': [value: boolean]
|
||||
confirm: []
|
||||
}>()
|
||||
|
||||
function close() {
|
||||
emit('update:show', false)
|
||||
}
|
||||
|
||||
function confirm() {
|
||||
emit('confirm')
|
||||
close()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BasicModal
|
||||
:visible="show"
|
||||
:custom-footer="true"
|
||||
destroy-on-close
|
||||
@update:visible="emit('update:show', $event)"
|
||||
>
|
||||
<h2 class="text-base font-semibold text-center mb-2 text-gray-800">
|
||||
وب اپلیکیشن بورس مس را به صفحه اصلی خود اضافه کنید
|
||||
</h2>
|
||||
|
||||
<div class="dauth-pwa-steps">
|
||||
<div class="dauth-pwa-step">
|
||||
<div class="dauth-pwa-step__icon">
|
||||
<img :src="shareAppleIcon" alt="Share" />
|
||||
</div>
|
||||
<p class="dauth-pwa-step__text">روی دکمه Share در نوار پایین کلیک کنید.</p>
|
||||
</div>
|
||||
|
||||
<div class="dauth-pwa-step">
|
||||
<div class="dauth-pwa-step__icon">
|
||||
<img :src="addToHomeScreenIcon" alt="Add to Home Screen" />
|
||||
</div>
|
||||
<p class="dauth-pwa-step__text">
|
||||
در منوی باز شده در قسمت پایین گزینه Add to Home Screen را انتخاب کنید.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="dauth-pwa-step">
|
||||
<div class="dauth-pwa-step__icon">
|
||||
<span class="text-blue-600 font-bold text-lg">Add</span>
|
||||
</div>
|
||||
<p class="dauth-pwa-step__text">در مرحله آخر در قسمت بالا روی Add کلیک کنید.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BasicButton class="w-full mt-4" type="primary" @click="confirm">
|
||||
متوجه شدم
|
||||
</BasicButton>
|
||||
</BasicModal>
|
||||
</template>
|
||||
@@ -0,0 +1,499 @@
|
||||
/* Premium desktop auth — split-panel SaaS login */
|
||||
|
||||
.dauth {
|
||||
min-height: 100vh;
|
||||
background: #f6f7f9;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.dauth__layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(380px, 1fr) minmax(420px, 520px);
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Brand panel — uses config primary color (same as buttons) */
|
||||
.dauth-brand {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 56px 64px;
|
||||
background: @App-primary-color;
|
||||
overflow: hidden;
|
||||
|
||||
&--boursecu {
|
||||
.dauth-brand__logo {
|
||||
max-width: 280px;
|
||||
max-height: 280px;
|
||||
width: min(100%, 280px);
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
&--soroushgold {
|
||||
.dauth-brand__logo {
|
||||
max-width: 220px;
|
||||
max-height: 220px;
|
||||
width: min(100%, 220px);
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
&__pattern {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
opacity: 0.04;
|
||||
background-image: radial-gradient(circle at 1px 1px, #fff 1px, transparent 0);
|
||||
background-size: 28px 28px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&__content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
max-width: 420px;
|
||||
}
|
||||
|
||||
&__logo {
|
||||
width: auto;
|
||||
max-width: 220px;
|
||||
height: auto;
|
||||
max-height: 72px;
|
||||
object-fit: contain;
|
||||
margin-bottom: 32px;
|
||||
|
||||
&--round {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-radius: 16px;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.03em;
|
||||
color: #ffffff;
|
||||
line-height: 1.25;
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
|
||||
&__tagline {
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
color: rgba(255, 255, 255, 0.72);
|
||||
line-height: 1.7;
|
||||
margin: 0 0 40px;
|
||||
}
|
||||
|
||||
&__features {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&__feature {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
|
||||
&__feature-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 8px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: #ffffff;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
position: absolute;
|
||||
bottom: 32px;
|
||||
right: 64px;
|
||||
left: 64px;
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
/* Form panel */
|
||||
.dauth-form-panel {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 48px 56px;
|
||||
}
|
||||
|
||||
.dauth-card {
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
background: #ffffff;
|
||||
border-radius: 16px;
|
||||
padding: 36px 40px;
|
||||
box-shadow:
|
||||
0 1px 2px rgba(15, 23, 42, 0.04),
|
||||
0 8px 24px rgba(15, 23, 42, 0.06);
|
||||
|
||||
&__header {
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
&__eyebrow {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #9ca3af;
|
||||
margin: 0 0 6px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.02em;
|
||||
color: #111827;
|
||||
margin: 0;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
&__subtitle {
|
||||
font-size: 13px;
|
||||
color: #6b7280;
|
||||
margin: 8px 0 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
/* Method toggle */
|
||||
.dauth-toggle {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 4px;
|
||||
padding: 4px;
|
||||
background: #f3f4f6;
|
||||
border-radius: 10px;
|
||||
margin-bottom: 24px;
|
||||
|
||||
&__btn {
|
||||
padding: 9px 12px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background: transparent;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
font-family: inherit;
|
||||
color: #6b7280;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
|
||||
|
||||
&--active {
|
||||
background: #ffffff;
|
||||
color: #111827;
|
||||
box-shadow: 0 1px 3px rgba(15, 23, 42, 0.08);
|
||||
}
|
||||
|
||||
&:hover:not(&--active) {
|
||||
color: #374151;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Form fields */
|
||||
.dauth-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
|
||||
&.ant-form-vertical :deep(.ant-form-item) {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
&.ant-form-vertical :deep(.ant-form-item-label) {
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
&.ant-form-vertical :deep(.ant-form-item-label > label) {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #374151;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
:deep(.ant-form-item) {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
:deep(.ant-form-item-label > label) {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
:deep(.ant-input),
|
||||
:deep(.ant-input-affix-wrapper) {
|
||||
border-radius: 10px;
|
||||
border-color: #e5e7eb;
|
||||
padding: 10px 14px;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&-focused {
|
||||
border-color: @App-primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-input-lg) {
|
||||
padding: 11px 14px;
|
||||
}
|
||||
|
||||
.dauth-toggle {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.dauth-actions,
|
||||
.dauth-switch {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* OTP */
|
||||
.dauth-otp {
|
||||
margin-top: 8px;
|
||||
|
||||
:deep(.otp-input) {
|
||||
width: 52px !important;
|
||||
height: 52px !important;
|
||||
border-radius: 10px !important;
|
||||
border: 1px solid #e5e7eb !important;
|
||||
font-size: 20px !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.dauth-phone-edit {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
margin: 16px 0 20px;
|
||||
font-size: 13px;
|
||||
|
||||
&__number {
|
||||
color: #9ca3af;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
&__btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: #374151;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
padding: 4px 8px;
|
||||
border-radius: 6px;
|
||||
transition: background 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
background: #f3f4f6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dauth-resend {
|
||||
margin-bottom: 20px;
|
||||
|
||||
:deep(.ant-btn) {
|
||||
border-radius: 10px;
|
||||
height: 42px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Actions */
|
||||
.dauth-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
margin-top: 8px;
|
||||
width: 100%;
|
||||
|
||||
&__submit {
|
||||
min-height: 44px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
:deep(.ant-btn),
|
||||
:deep(button),
|
||||
:deep(.noname-base-button) {
|
||||
border-radius: 10px;
|
||||
min-height: 44px;
|
||||
height: auto;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.dauth-actions-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.dauth-switch {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
margin-top: 20px;
|
||||
padding-top: 4px;
|
||||
font-size: 13px;
|
||||
color: #6b7280;
|
||||
flex-shrink: 0;
|
||||
|
||||
&__link {
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: @App-primary-color;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
padding: 0;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Garoosi extras */
|
||||
.dauth-garoosi-links {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.dauth-link-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
padding: 10px 16px;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 10px;
|
||||
background: #ffffff;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #374151;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
transition: background 0.15s ease, border-color 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
background: #f9fafb;
|
||||
border-color: #d1d5db;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
&--primary {
|
||||
background: @App-primary-color;
|
||||
border-color: @App-primary-color;
|
||||
color: #ffffff;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.92;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* PWA guide modal */
|
||||
.dauth-pwa-steps {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
margin: 20px 0 8px;
|
||||
}
|
||||
|
||||
.dauth-pwa-step {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
|
||||
&__icon {
|
||||
flex-shrink: 0;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 10px;
|
||||
background: #f0f4ff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 8px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
&__text {
|
||||
font-size: 13px;
|
||||
color: #374151;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.dauth__layout {
|
||||
grid-template-columns: minmax(300px, 1fr) minmax(340px, 1fr);
|
||||
}
|
||||
|
||||
.dauth-brand {
|
||||
padding: 40px 36px;
|
||||
|
||||
&__footer {
|
||||
right: 36px;
|
||||
left: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.dauth-form-panel {
|
||||
padding: 32px 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-form--desktop {
|
||||
:deep(.ant-form-item) {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
:deep(.ant-form-item-label > label) {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #374151;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user