diff --git a/archive.php b/archive.php index 1288725..2e9cf9f 100644 --- a/archive.php +++ b/archive.php @@ -1,79 +1,278 @@
'; + echo '

فروشگاه فعال نیست

'; + echo '

برای مشاهده محصولات، افزونه ووکامرس را فعال کنید.

'; + echo '
'; + get_footer(); + return; +} + +// داده‌های صفحه + $banner_img = get_option( 'motayeb_shop_banner', '' ); + $banner_img = $banner_img ? $banner_img : 'https://picsum.photos/seed/forest-shop/1600/600'; + $is_category = is_product_category(); + $current_term = $is_category ? get_queried_object() : null; + +// بررسی اینکه آیا سایدبار فیلتر داره یا خیر + $has_shop_sidebar = is_active_sidebar( 'sidebar-shop' ); ?> - -
-
-
-

مجله سلامت مطیب

-

جدیدترین مقالات و مطالب آموزشی در زمینه سلامت، تغذیه و سبک زندگی ارگانیک

+ +
+
+ <?php echo esc_attr( $is_category && $current_term ? $current_term->name : 'فروشگاه مطیب' ); ?> +
+ +
+

+ +

+ description ) : ?> +

+ description ) ); ?> +

+
- -
-
-
- - - name : 'سلامت'; - $cat_color = 'bg-forest-50 dark:bg-forest-900/30 text-forest-500 dark:text-forest-300'; - if ( $cat_name === 'دستور پخت' || $cat_name === 'غذا' ) { - $cat_color = 'bg-honey-50 dark:bg-honey-900/30 text-honey-400'; - } elseif ( $cat_name === 'سبک زندگی' ) { - $cat_color = 'bg-emerald-50 dark:bg-emerald-900/30 text-emerald-500'; - } - $image = wp_get_attachment_image_src( get_post_thumbnail_id(), 'medium' ); - $img_src = $image ? $image[0] : 'https://picsum.photos/seed/' . get_the_ID() . '/600/400.jpg'; - ?> - - + +
+
+ + 'lucide:leaf', 2 => 'lucide:truck', 3 => 'lucide:shield-check', 4 => 'lucide:package' ); + $icon = get_option( 'motayeb_feature_' . $i . '_icon', $default_icons[ $i ] ); + $text = get_option( 'motayeb_feature_' . $i . '_text', 'ویژگی ' . $i ); + ?> +
+ + +
+ +
+
+ + + 'خانه', 'url' => home_url( '/' ) ), + array( 'name' => 'فروشگاه', 'url' => get_permalink( wc_get_page_id( 'shop' ) ) ), + ); + // افزودن دسته‌بندی‌های والد + $parents = get_ancestors( $current_term->term_id, 'product_cat' ); + $parents = array_reverse( $parents ); + foreach ( $parents as $parent_id ) { + $parent = get_term( $parent_id, 'product_cat' ); + if ( $parent && ! is_wp_error( $parent ) ) { + $crumbs[] = array( 'name' => $parent->name, 'url' => get_term_link( $parent ) ); + } + } + $crumbs[] = array( 'name' => $current_term->name, 'url' => get_term_link( $current_term ) ); + + $breadcrumb_schema = array( + '@context' => 'https://schema.org', + '@type' => 'BreadcrumbList', + 'itemListElement' => array(), + ); + foreach ( $crumbs as $index => $crumb ) { + $breadcrumb_schema['itemListElement'][] = array( + '@type' => 'ListItem', + 'position' => $index + 1, + 'name' => $crumb['name'], + 'item' => $crumb['url'], + ); + } + ?> +
+ + + + - -
- 2, - 'prev_text' => '', - 'next_text' => '', - 'screen_reader_text' => ' ', - 'class' => 'flex justify-center gap-2', - ) ); ?> + +
+
+ + + +
+ + + + +
+ +
+
+ +
+
+ +
+
+ + + '; + the_widget( 'WC_Widget_Price_Filter' ); + echo '
'; + } + ?> + + + +
+ + + +
+
+ +
+ +
+ +

محصولی یافت نشد.

+ + + نمایش همه محصولات + +
+ +
+ + :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(-0.5rem * var(--tw-space-x-reverse)); + margin-left: calc(-0.5rem * calc(1 - var(--tw-space-x-reverse))); +} + +.space-y-1 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.25rem * var(--tw-space-y-reverse)); +} + +.space-y-2 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); +} + +.space-y-3 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); +} + +.space-y-4 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1rem * var(--tw-space-y-reverse)); +} + +.space-y-6 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1.5rem * var(--tw-space-y-reverse)); +} + +.space-x-reverse > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 1; +} + +.overflow-hidden { + overflow: hidden; +} + +.overflow-x-auto { + overflow-x: auto; +} + +.overflow-y-auto { + overflow-y: auto; +} + +.scroll-smooth { + scroll-behavior: smooth; +} + +.whitespace-nowrap { + white-space: nowrap; +} + +.rounded-2xl { + border-radius: 1rem; +} + +.rounded-3xl { + border-radius: 1.5rem; +} + +.rounded-full { + border-radius: 9999px; +} + +.rounded-lg { + border-radius: 0.5rem; +} + +.rounded-xl { + border-radius: 0.75rem; +} + +.border { + border-width: 1px; +} + +.border-2 { + border-width: 2px; +} + +.border-x { + border-left-width: 1px; + border-right-width: 1px; +} + +.border-x-2 { + border-left-width: 2px; + border-right-width: 2px; +} + +.border-y { + border-top-width: 1px; + border-bottom-width: 1px; +} + +.border-b { + border-bottom-width: 1px; +} + +.border-b-2 { + border-bottom-width: 2px; +} + +.border-t { + border-top-width: 1px; +} + +.border-dashed { + border-style: dashed; +} + +.border-cream-200 { + --tw-border-opacity: 1; + border-color: rgb(235 227 213 / var(--tw-border-opacity, 1)); +} + +.border-cream-200\/50 { + border-color: rgb(235 227 213 / 0.5); +} + +.border-forest-500 { + --tw-border-opacity: 1; + border-color: rgb(45 95 63 / var(--tw-border-opacity, 1)); +} + +.border-red-200 { + --tw-border-opacity: 1; + border-color: rgb(254 202 202 / var(--tw-border-opacity, 1)); +} + +.border-transparent { + border-color: transparent; +} + +.border-white\/10 { + border-color: rgb(255 255 255 / 0.1); +} + +.bg-amber-50 { + --tw-bg-opacity: 1; + background-color: rgb(255 251 235 / var(--tw-bg-opacity, 1)); +} + +.bg-black\/50 { + background-color: rgb(0 0 0 / 0.5); +} + +.bg-blue-50 { + --tw-bg-opacity: 1; + background-color: rgb(239 246 255 / var(--tw-bg-opacity, 1)); +} + +.bg-cream-100 { + --tw-bg-opacity: 1; + background-color: rgb(245 240 232 / var(--tw-bg-opacity, 1)); +} + +.bg-cream-100\/80 { + background-color: rgb(245 240 232 / 0.8); +} + +.bg-cream-200 { + --tw-bg-opacity: 1; + background-color: rgb(235 227 213 / var(--tw-bg-opacity, 1)); +} + +.bg-cream-400 { + --tw-bg-opacity: 1; + background-color: rgb(196 180 154 / var(--tw-bg-opacity, 1)); +} + +.bg-cream-50 { + --tw-bg-opacity: 1; + background-color: rgb(253 251 247 / var(--tw-bg-opacity, 1)); +} + +.bg-earth-400 { + --tw-bg-opacity: 1; + background-color: rgb(139 90 60 / var(--tw-bg-opacity, 1)); +} + +.bg-emerald-50 { + --tw-bg-opacity: 1; + background-color: rgb(236 253 245 / var(--tw-bg-opacity, 1)); +} + +.bg-emerald-500 { + --tw-bg-opacity: 1; + background-color: rgb(16 185 129 / var(--tw-bg-opacity, 1)); +} + +.bg-forest-100 { + --tw-bg-opacity: 1; + background-color: rgb(198 230 207 / var(--tw-bg-opacity, 1)); +} + +.bg-forest-50 { + --tw-bg-opacity: 1; + background-color: rgb(232 245 236 / var(--tw-bg-opacity, 1)); +} + +.bg-forest-500 { + --tw-bg-opacity: 1; + background-color: rgb(45 95 63 / var(--tw-bg-opacity, 1)); +} + +.bg-honey-100 { + --tw-bg-opacity: 1; + background-color: rgb(249 230 208 / var(--tw-bg-opacity, 1)); +} + +.bg-honey-400 { + --tw-bg-opacity: 1; + background-color: rgb(212 165 116 / var(--tw-bg-opacity, 1)); +} + +.bg-honey-50 { + --tw-bg-opacity: 1; + background-color: rgb(253 245 237 / var(--tw-bg-opacity, 1)); +} + +.bg-red-50 { + --tw-bg-opacity: 1; + background-color: rgb(254 242 242 / var(--tw-bg-opacity, 1)); +} + +.bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1)); +} + +.bg-transparent { + background-color: transparent; +} + +.bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)); +} + +.bg-white\/10 { + background-color: rgb(255 255 255 / 0.1); +} + +.bg-white\/20 { + background-color: rgb(255 255 255 / 0.2); +} + +.bg-white\/30 { + background-color: rgb(255 255 255 / 0.3); +} + +.bg-white\/60 { + background-color: rgb(255 255 255 / 0.6); +} + +.bg-white\/80 { + background-color: rgb(255 255 255 / 0.8); +} + +.bg-white\/90 { + background-color: rgb(255 255 255 / 0.9); +} + +.bg-gradient-to-t { + background-image: linear-gradient(to top, var(--tw-gradient-stops)); +} + +.from-forest-500\/30 { + --tw-gradient-from: rgb(45 95 63 / 0.3) var(--tw-gradient-from-position); + --tw-gradient-to: rgb(45 95 63 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.from-forest-900\/90 { + --tw-gradient-from: rgb(10 23 16 / 0.9) var(--tw-gradient-from-position); + --tw-gradient-to: rgb(10 23 16 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.via-forest-700\/70 { + --tw-gradient-to: rgb(28 59 40 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), rgb(28 59 40 / 0.7) var(--tw-gradient-via-position), var(--tw-gradient-to); +} + +.to-forest-500\/40 { + --tw-gradient-to: rgb(45 95 63 / 0.4) var(--tw-gradient-to-position); +} + +.to-transparent { + --tw-gradient-to: transparent var(--tw-gradient-to-position); +} + +.fill-cream-100 { + fill: #F5F0E8; +} + +.object-cover { + -o-object-fit: cover; + object-fit: cover; +} + +.p-2 { + padding: 0.5rem; +} + +.p-3 { + padding: 0.75rem; +} + +.p-4 { + padding: 1rem; +} + +.p-5 { + padding: 1.25rem; +} + +.p-6 { + padding: 1.5rem; +} + +.px-1 { + padding-left: 0.25rem; + padding-right: 0.25rem; +} + +.px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.px-2\.5 { + padding-left: 0.625rem; + padding-right: 0.625rem; +} + +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} + +.px-5 { + padding-left: 1.25rem; + padding-right: 1.25rem; +} + +.px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; +} + +.px-8 { + padding-left: 2rem; + padding-right: 2rem; +} + +.py-0\.5 { + padding-top: 0.125rem; + padding-bottom: 0.125rem; +} + +.py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +.py-1\.5 { + padding-top: 0.375rem; + padding-bottom: 0.375rem; +} + +.py-12 { + padding-top: 3rem; + padding-bottom: 3rem; +} + +.py-16 { + padding-top: 4rem; + padding-bottom: 4rem; +} + +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.py-2\.5 { + padding-top: 0.625rem; + padding-bottom: 0.625rem; +} + +.py-20 { + padding-top: 5rem; + padding-bottom: 5rem; +} + +.py-3 { + padding-top: 0.75rem; + padding-bottom: 0.75rem; +} + +.py-3\.5 { + padding-top: 0.875rem; + padding-bottom: 0.875rem; +} + +.py-4 { + padding-top: 1rem; + padding-bottom: 1rem; +} + +.py-5 { + padding-top: 1.25rem; + padding-bottom: 1.25rem; +} + +.py-6 { + padding-top: 1.5rem; + padding-bottom: 1.5rem; +} + +.py-8 { + padding-top: 2rem; + padding-bottom: 2rem; +} + +.pb-1 { + padding-bottom: 0.25rem; +} + +.pb-3 { + padding-bottom: 0.75rem; +} + +.pb-4 { + padding-bottom: 1rem; +} + +.pb-6 { + padding-bottom: 1.5rem; +} + +.pb-8 { + padding-bottom: 2rem; +} + +.pt-16 { + padding-top: 4rem; +} + +.pt-3 { + padding-top: 0.75rem; +} + +.pt-4 { + padding-top: 1rem; +} + +.pt-8 { + padding-top: 2rem; +} + +.text-left { + text-align: left; +} + +.text-center { + text-align: center; +} + +.text-right { + text-align: right; +} + +.font-inter { + font-family: Inter, system-ui, sans-serif; +} + +.text-2xl { + font-size: 1.5rem; + line-height: 2rem; +} + +.text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; +} + +.text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; +} + +.text-6xl { + font-size: 3.75rem; + line-height: 1; +} + +.text-\[10px\] { + font-size: 10px; +} + +.text-\[9px\] { + font-size: 9px; +} + +.text-base { + font-size: 1rem; + line-height: 1.5rem; +} + +.text-lg { + font-size: 1.125rem; + line-height: 1.75rem; +} + +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; +} + +.text-xl { + font-size: 1.25rem; + line-height: 1.75rem; +} + +.text-xs { + font-size: 0.75rem; + line-height: 1rem; +} + +.font-bold { + font-weight: 700; +} + +.font-extrabold { + font-weight: 800; +} + +.font-medium { + font-weight: 500; +} + +.font-semibold { + font-weight: 600; +} + +.leading-7 { + line-height: 1.75rem; +} + +.leading-\[1\.1\] { + line-height: 1.1; +} + +.leading-none { + line-height: 1; +} + +.leading-relaxed { + line-height: 1.625; +} + +.leading-tight { + line-height: 1.25; +} + +.tracking-wider { + letter-spacing: 0.05em; +} + +.tracking-widest { + letter-spacing: 0.1em; +} + +.text-amber-400 { + --tw-text-opacity: 1; + color: rgb(251 191 36 / var(--tw-text-opacity, 1)); +} + +.text-amber-500 { + --tw-text-opacity: 1; + color: rgb(245 158 11 / var(--tw-text-opacity, 1)); +} + +.text-blue-400 { + --tw-text-opacity: 1; + color: rgb(96 165 250 / var(--tw-text-opacity, 1)); +} + +.text-blue-500 { + --tw-text-opacity: 1; + color: rgb(59 130 246 / var(--tw-text-opacity, 1)); +} + +.text-cream-300 { + --tw-text-opacity: 1; + color: rgb(221 210 191 / var(--tw-text-opacity, 1)); +} + +.text-cream-400 { + --tw-text-opacity: 1; + color: rgb(196 180 154 / var(--tw-text-opacity, 1)); +} + +.text-cream-500 { + --tw-text-opacity: 1; + color: rgb(169 148 120 / var(--tw-text-opacity, 1)); +} + +.text-dark-muted { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity, 1)); +} + +.text-earth-400 { + --tw-text-opacity: 1; + color: rgb(139 90 60 / var(--tw-text-opacity, 1)); +} + +.text-emerald-400 { + --tw-text-opacity: 1; + color: rgb(52 211 153 / var(--tw-text-opacity, 1)); +} + +.text-emerald-500 { + --tw-text-opacity: 1; + color: rgb(16 185 129 / var(--tw-text-opacity, 1)); +} + +.text-emerald-600 { + --tw-text-opacity: 1; + color: rgb(5 150 105 / var(--tw-text-opacity, 1)); +} + +.text-forest-500 { + --tw-text-opacity: 1; + color: rgb(45 95 63 / var(--tw-text-opacity, 1)); +} + +.text-green-400 { + --tw-text-opacity: 1; + color: rgb(74 222 128 / var(--tw-text-opacity, 1)); +} + +.text-honey-300 { + --tw-text-opacity: 1; + color: rgb(232 172 106 / var(--tw-text-opacity, 1)); +} + +.text-honey-400 { + --tw-text-opacity: 1; + color: rgb(212 165 116 / var(--tw-text-opacity, 1)); +} + +.text-indigo-400 { + --tw-text-opacity: 1; + color: rgb(129 140 248 / var(--tw-text-opacity, 1)); +} + +.text-orange-400 { + --tw-text-opacity: 1; + color: rgb(251 146 60 / var(--tw-text-opacity, 1)); +} + +.text-pink-400 { + --tw-text-opacity: 1; + color: rgb(244 114 182 / var(--tw-text-opacity, 1)); +} + +.text-purple-400 { + --tw-text-opacity: 1; + color: rgb(192 132 252 / var(--tw-text-opacity, 1)); +} + +.text-red-400 { + --tw-text-opacity: 1; + color: rgb(248 113 113 / var(--tw-text-opacity, 1)); +} + +.text-red-500 { + --tw-text-opacity: 1; + color: rgb(239 68 68 / var(--tw-text-opacity, 1)); +} + +.text-red-600 { + --tw-text-opacity: 1; + color: rgb(220 38 38 / var(--tw-text-opacity, 1)); +} + +.text-rose-400 { + --tw-text-opacity: 1; + color: rgb(251 113 133 / var(--tw-text-opacity, 1)); +} + +.text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity, 1)); +} + +.text-white\/50 { + color: rgb(255 255 255 / 0.5); +} + +.text-white\/60 { + color: rgb(255 255 255 / 0.6); +} + +.text-white\/70 { + color: rgb(255 255 255 / 0.7); +} + +.text-white\/90 { + color: rgb(255 255 255 / 0.9); +} + +.line-through { + text-decoration-line: line-through; +} + +.opacity-0 { + opacity: 0; +} + +.opacity-10 { + opacity: 0.1; +} + +.shadow { + --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-2xl { + --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); + --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-lg { + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-sm { + --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-xl { + --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-forest-500\/10 { + --tw-shadow-color: rgb(45 95 63 / 0.1); + --tw-shadow: var(--tw-shadow-colored); +} + +.shadow-forest-500\/20 { + --tw-shadow-color: rgb(45 95 63 / 0.2); + --tw-shadow: var(--tw-shadow-colored); +} + +.shadow-forest-500\/25 { + --tw-shadow-color: rgb(45 95 63 / 0.25); + --tw-shadow: var(--tw-shadow-colored); +} + +.outline-none { + outline: 2px solid transparent; + outline-offset: 2px; +} + +.blur { + --tw-blur: blur(8px); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + +.drop-shadow-md { + --tw-drop-shadow: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06)); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + +.filter { + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + +.backdrop-blur { + --tw-backdrop-blur: blur(8px); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} + +.backdrop-blur-lg { + --tw-backdrop-blur: blur(16px); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} + +.backdrop-blur-md { + --tw-backdrop-blur: blur(12px); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} + +.backdrop-blur-xl { + --tw-backdrop-blur: blur(24px); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} + +.backdrop-filter { + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} + +.transition { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.transition-all { + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.transition-colors { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.transition-transform { + transition-property: transform; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.duration-300 { + transition-duration: 300ms; +} + +.duration-500 { + transition-duration: 500ms; +} + +.ease-in-out { + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +.ease-out { + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} + +/* فیلدهای فرم ووکامرس */ + +.woocommerce form .form-row .input-text, + .woocommerce form .form-row textarea, + .woocommerce form .form-row select, + .select2-container .select2-selection--single, + #add_payment_method #payment ul.payment_methods li, + .woocommerce-checkout #payment ul.payment_methods li { + background-color: #FDFBF7 !important; + border: 1px solid #EBE3D5 !important; + border-radius: 12px !important; + color: #734A30 !important; + box-shadow: none !important; + outline: none !important; + transition: 0.3s ease !important; +} + +.woocommerce form .form-row .input-text:focus, + .woocommerce form .form-row textarea:focus, + .woocommerce form .form-row select:focus, + .select2-container .select2-selection--single:focus { + border-color: #2D5F3F !important; + background-color: #ffffff !important; +} + +/* دارک مود */ + +.dark .woocommerce form .form-row .input-text, + .dark .woocommerce form .form-row textarea, + .dark .woocommerce form .form-row select, + .dark .select2-container .select2-selection--single, + .dark #add_payment_method #payment ul.payment_methods li, + .dark .woocommerce-checkout #payment ul.payment_methods li { + background-color: #1A1D23 !important; + border-color: #2E333D !important; + color: #E8E6E3 !important; +} + +.dark .woocommerce form .form-row .input-text:focus, + .dark .woocommerce form .form-row textarea:focus, + .dark .woocommerce form .form-row select:focus, + .dark .select2-container .select2-selection--single:focus { + border-color: #6fb88a !important; +} + +/* برچسب‌ها */ + +.woocommerce form .form-row label { + display: block !important; + font-weight: 700 !important; + font-size: 14px !important; + margin-bottom: 8px !important; + color: #734A30 !important; +} + +/* رادیو باتن‌های درگاه پرداخت */ + +#add_payment_method #payment ul.payment_methods li input[type="radio"], + .woocommerce-checkout #payment ul.payment_methods li input[type="radio"] { + accent-color: #2D5F3F !important; +} + +/* جدول خلاصه سفارش */ + +/* ستاره‌های امتیاز ووکامرس با FontAwesome */ + +.comment-form-rating p.stars { + direction: rtl; + margin: 10px 0; + display: inline-block; +} + +.comment-form-rating p.stars a { + font-size: 0 !important; + display: inline-block; + width: 1.8rem; + height: 1.8rem; + position: relative; + text-decoration: none; + margin-left: 5px; +} + +.comment-form-rating p.stars a::before { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; + content: "\f005"; + font-size: 1.8rem; + position: absolute; + top: 0; + right: 0; + color: #ccc; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} + +.comment-form-rating p.stars a:hover::before, + .comment-form-rating p.stars a.active::before, + .comment-form-rating p.stars a.selected::before { + font-weight: 900; + color: #2D5F3F; +} + +/* ============================================================ + فونت Vazirmatn محلی — به جای CDN گوگل + ============================================================ */ + +@font-face { + font-family: 'Vazirmatn'; + + src: url('../assets/fonts/Vazirmatn-Regular.woff2') format('woff2'); + + font-weight: 400; + + font-style: normal; + + font-display: swap; +} + +@font-face { + font-family: 'Vazirmatn'; + + src: url('../assets/fonts/Vazirmatn-Bold.woff2') format('woff2'); + + font-weight: 700; + + font-style: normal; + + font-display: swap; +} + +/* ============================================================ + تنظیمات پایه در لایه base + ============================================================ */ + +/* ============================================================ + کلاس‌های کاربردی اختصاصی + ============================================================ */ + +/* ============================================================ + استایل‌های ووکامرس — اورراید فرم‌ها + (قبلاً داخل header.php inline بود، اینجا به جاش منتقل شد) + ============================================================ */ + +.placeholder\:text-cream-400::-moz-placeholder { + --tw-text-opacity: 1; + color: rgb(196 180 154 / var(--tw-text-opacity, 1)); +} + +.placeholder\:text-cream-400::placeholder { + --tw-text-opacity: 1; + color: rgb(196 180 154 / var(--tw-text-opacity, 1)); +} + +.hover\:-translate-y-0\.5:hover { + --tw-translate-y: -0.125rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.hover\:-translate-y-1:hover { + --tw-translate-y: -0.25rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.hover\:scale-110:hover { + --tw-scale-x: 1.1; + --tw-scale-y: 1.1; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.hover\:gap-2:hover { + gap: 0.5rem; +} + +.hover\:border-forest-300:hover { + --tw-border-opacity: 1; + border-color: rgb(111 184 138 / var(--tw-border-opacity, 1)); +} + +.hover\:border-forest-500:hover { + --tw-border-opacity: 1; + border-color: rgb(45 95 63 / var(--tw-border-opacity, 1)); +} + +.hover\:border-red-400:hover { + --tw-border-opacity: 1; + border-color: rgb(248 113 113 / var(--tw-border-opacity, 1)); +} + +.hover\:bg-cream-100:hover { + --tw-bg-opacity: 1; + background-color: rgb(245 240 232 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-cream-200:hover { + --tw-bg-opacity: 1; + background-color: rgb(235 227 213 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-cream-300:hover { + --tw-bg-opacity: 1; + background-color: rgb(221 210 191 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-cream-50:hover { + --tw-bg-opacity: 1; + background-color: rgb(253 251 247 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-forest-50:hover { + --tw-bg-opacity: 1; + background-color: rgb(232 245 236 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-forest-500:hover { + --tw-bg-opacity: 1; + background-color: rgb(45 95 63 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-forest-600:hover { + --tw-bg-opacity: 1; + background-color: rgb(37 77 52 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-red-50:hover { + --tw-bg-opacity: 1; + background-color: rgb(254 242 242 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-white:hover { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-white\/20:hover { + background-color: rgb(255 255 255 / 0.2); +} + +.hover\:text-earth-400:hover { + --tw-text-opacity: 1; + color: rgb(139 90 60 / var(--tw-text-opacity, 1)); +} + +.hover\:text-forest-500:hover { + --tw-text-opacity: 1; + color: rgb(45 95 63 / var(--tw-text-opacity, 1)); +} + +.hover\:text-honey-300:hover { + --tw-text-opacity: 1; + color: rgb(232 172 106 / var(--tw-text-opacity, 1)); +} + +.hover\:text-red-500:hover { + --tw-text-opacity: 1; + color: rgb(239 68 68 / var(--tw-text-opacity, 1)); +} + +.hover\:text-white:hover { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity, 1)); +} + +.hover\:opacity-80:hover { + opacity: 0.8; +} + +.hover\:shadow-lg:hover { + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.hover\:shadow-xl:hover { + --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.focus\:border-forest-500:focus { + --tw-border-opacity: 1; + border-color: rgb(45 95 63 / var(--tw-border-opacity, 1)); +} + +.group:hover .group-hover\:visible { + visibility: visible; +} + +.group:hover .group-hover\:scale-105 { + --tw-scale-x: 1.05; + --tw-scale-y: 1.05; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.group:hover .group-hover\:scale-110 { + --tw-scale-x: 1.1; + --tw-scale-y: 1.1; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.group:hover .group-hover\:text-forest-500 { + --tw-text-opacity: 1; + color: rgb(45 95 63 / var(--tw-text-opacity, 1)); +} + +.group:hover .group-hover\:opacity-100 { + opacity: 1; +} + +.dark\:left-0\.5:is(.dark *) { + left: 0.125rem; +} + +.dark\:right-auto:is(.dark *) { + right: auto; +} + +.dark\:block:is(.dark *) { + display: block; +} + +.dark\:hidden:is(.dark *) { + display: none; +} + +.dark\:border-dark-border:is(.dark *) { + --tw-border-opacity: 1; + border-color: rgb(46 51 61 / var(--tw-border-opacity, 1)); +} + +.dark\:border-dark-border\/50:is(.dark *) { + border-color: rgb(46 51 61 / 0.5); +} + +.dark\:border-forest-300:is(.dark *) { + --tw-border-opacity: 1; + border-color: rgb(111 184 138 / var(--tw-border-opacity, 1)); +} + +.dark\:border-red-800:is(.dark *) { + --tw-border-opacity: 1; + border-color: rgb(153 27 27 / var(--tw-border-opacity, 1)); +} + +.dark\:bg-amber-900\/20:is(.dark *) { + background-color: rgb(120 53 15 / 0.2); +} + +.dark\:bg-blue-900\/30:is(.dark *) { + background-color: rgb(30 58 138 / 0.3); +} + +.dark\:bg-dark-bg:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(26 29 35 / var(--tw-bg-opacity, 1)); +} + +.dark\:bg-dark-bg\/80:is(.dark *) { + background-color: rgb(26 29 35 / 0.8); +} + +.dark\:bg-dark-border:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(46 51 61 / var(--tw-bg-opacity, 1)); +} + +.dark\:bg-dark-card:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(34 38 46 / var(--tw-bg-opacity, 1)); +} + +.dark\:bg-dark-card\/60:is(.dark *) { + background-color: rgb(34 38 46 / 0.6); +} + +.dark\:bg-dark-card\/80:is(.dark *) { + background-color: rgb(34 38 46 / 0.8); +} + +.dark\:bg-dark-card\/90:is(.dark *) { + background-color: rgb(34 38 46 / 0.9); +} + +.dark\:bg-emerald-900\/20:is(.dark *) { + background-color: rgb(6 78 59 / 0.2); +} + +.dark\:bg-emerald-900\/30:is(.dark *) { + background-color: rgb(6 78 59 / 0.3); +} + +.dark\:bg-forest-300:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(111 184 138 / var(--tw-bg-opacity, 1)); +} + +.dark\:bg-forest-500:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(45 95 63 / var(--tw-bg-opacity, 1)); +} + +.dark\:bg-forest-700:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(28 59 40 / var(--tw-bg-opacity, 1)); +} + +.dark\:bg-forest-800:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(19 41 28 / var(--tw-bg-opacity, 1)); +} + +.dark\:bg-forest-900\/20:is(.dark *) { + background-color: rgb(10 23 16 / 0.2); +} + +.dark\:bg-forest-900\/30:is(.dark *) { + background-color: rgb(10 23 16 / 0.3); +} + +.dark\:bg-honey-800:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(90 61 32 / var(--tw-bg-opacity, 1)); +} + +.dark\:bg-honey-900\/20:is(.dark *) { + background-color: rgb(58 38 18 / 0.2); +} + +.dark\:bg-honey-900\/30:is(.dark *) { + background-color: rgb(58 38 18 / 0.3); +} + +.dark\:bg-red-900\/20:is(.dark *) { + background-color: rgb(127 29 29 / 0.2); +} + +.dark\:fill-dark-bg:is(.dark *) { + fill: #1A1D23; +} + +.dark\:text-dark-border:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(46 51 61 / var(--tw-text-opacity, 1)); +} + +.dark\:text-dark-muted:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity, 1)); +} + +.dark\:text-dark-text:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(232 230 227 / var(--tw-text-opacity, 1)); +} + +.dark\:text-emerald-400:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(52 211 153 / var(--tw-text-opacity, 1)); +} + +.dark\:text-forest-300:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(111 184 138 / var(--tw-text-opacity, 1)); +} + +.dark\:text-red-400:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(248 113 113 / var(--tw-text-opacity, 1)); +} + +.dark\:placeholder\:text-dark-muted:is(.dark *)::-moz-placeholder { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity, 1)); +} + +.dark\:placeholder\:text-dark-muted:is(.dark *)::placeholder { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity, 1)); +} + +.dark\:hover\:border-forest-300:hover:is(.dark *) { + --tw-border-opacity: 1; + border-color: rgb(111 184 138 / var(--tw-border-opacity, 1)); +} + +.dark\:hover\:bg-dark-bg:hover:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(26 29 35 / var(--tw-bg-opacity, 1)); +} + +.dark\:hover\:bg-dark-border:hover:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(46 51 61 / var(--tw-bg-opacity, 1)); +} + +.dark\:hover\:bg-dark-card:hover:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(34 38 46 / var(--tw-bg-opacity, 1)); +} + +.dark\:hover\:bg-forest-900:hover:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(10 23 16 / var(--tw-bg-opacity, 1)); +} + +.dark\:hover\:bg-forest-900\/30:hover:is(.dark *) { + background-color: rgb(10 23 16 / 0.3); +} + +.dark\:hover\:bg-red-900\/20:hover:is(.dark *) { + background-color: rgb(127 29 29 / 0.2); +} + +.dark\:hover\:text-forest-300:hover:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(111 184 138 / var(--tw-text-opacity, 1)); +} + +.dark\:focus\:border-forest-300:focus:is(.dark *) { + --tw-border-opacity: 1; + border-color: rgb(111 184 138 / var(--tw-border-opacity, 1)); +} + +.group:hover .dark\:group-hover\:text-forest-300:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(111 184 138 / var(--tw-text-opacity, 1)); +} + +@media (min-width: 640px) { + .sm\:flex-row { + flex-direction: row; + } +} + +@media (min-width: 768px) { + .md\:-left-8 { + left: -2rem; + } + + .md\:-right-8 { + right: -2rem; + } + + .md\:bottom-8 { + bottom: 2rem; + } + + .md\:top-8 { + top: 2rem; + } + + .md\:col-span-1 { + grid-column: span 1 / span 1; + } + + .md\:col-span-2 { + grid-column: span 2 / span 2; + } + + .md\:mx-0 { + margin-left: 0px; + margin-right: 0px; + } + + .md\:block { + display: block; + } + + .md\:flex { + display: flex; + } + + .md\:hidden { + display: none; + } + + .md\:h-20 { + height: 5rem; + } + + .md\:h-56 { + height: 14rem; + } + + .md\:h-\[450px\] { + height: 450px; + } + + .md\:h-\[500px\] { + height: 500px; + } + + .md\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .md\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .md\:grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); + } + + .md\:flex-row { + flex-direction: row; + } + + .md\:justify-start { + justify-content: flex-start; + } + + .md\:gap-12 { + gap: 3rem; + } + + .md\:gap-4 { + gap: 1rem; + } + + .md\:gap-6 { + gap: 1.5rem; + } + + .md\:gap-8 { + gap: 2rem; + } + + .md\:p-5 { + padding: 1.25rem; + } + + .md\:p-8 { + padding: 2rem; + } + + .md\:px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; + } + + .md\:py-12 { + padding-top: 3rem; + padding-bottom: 3rem; + } + + .md\:py-16 { + padding-top: 4rem; + padding-bottom: 4rem; + } + + .md\:py-20 { + padding-top: 5rem; + padding-bottom: 5rem; + } + + .md\:py-24 { + padding-top: 6rem; + padding-bottom: 6rem; + } + + .md\:py-28 { + padding-top: 7rem; + padding-bottom: 7rem; + } + + .md\:pb-12 { + padding-bottom: 3rem; + } + + .md\:pt-\[104px\] { + padding-top: 104px; + } + + .md\:text-right { + text-align: right; + } + + .md\:text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; + } + + .md\:text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; + } + + .md\:text-6xl { + font-size: 3.75rem; + line-height: 1; + } + + .md\:text-8xl { + font-size: 6rem; + line-height: 1; + } + + .md\:text-base { + font-size: 1rem; + line-height: 1.5rem; + } + + .md\:text-lg { + font-size: 1.125rem; + line-height: 1.75rem; + } + + .md\:text-sm { + font-size: 0.875rem; + line-height: 1.25rem; + } +} + +@media (min-width: 1024px) { + .lg\:sticky { + position: sticky; + } + + .lg\:top-28 { + top: 7rem; + } + + .lg\:-mt-12 { + margin-top: -3rem; + } + + .lg\:h-\[500px\] { + height: 500px; + } + + .lg\:w-1\/4 { + width: 25%; + } + + .lg\:w-3\/4 { + width: 75%; + } + + .lg\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .lg\:grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); + } + + .lg\:grid-cols-5 { + grid-template-columns: repeat(5, minmax(0, 1fr)); + } + + .lg\:flex-row { + flex-direction: row; + } + + .lg\:gap-12 { + gap: 3rem; + } + + .lg\:text-5xl { + font-size: 3rem; + line-height: 1; + } + + .lg\:text-7xl { + font-size: 4.5rem; + line-height: 1; + } +} + +@media (min-width: 1280px) { + .xl\:w-1\/5 { + width: 20%; + } + + .xl\:w-4\/5 { + width: 80%; + } +} \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js index c8fb5aa..cc5f847 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,76 +1,153 @@ +/** + * اسکریپت اصلی تم مطیب + * + * @package Motayeb + * @version 1.0.1 + * + * تغییرات نسخه ۱.۰.۱: + * - persist شدن سبد خرید و علاقه‌مندی‌ها در localStorage + * - persist شدن دارک مود در کوکی (هماهنگ با PHP body_class) + * - جلوگیری از XSS با escapeHtml روی همه ورودی‌های داینامیک + * - guard کردن motayeb_ajax + * - بهبود مدیریت خطای fetch + * - رفع toggleWishlist و setRating + * - استفاده از کلاس‌های Tailwind در renderStars + */ + // ============================================ -// داده‌های محصولات (برای جستجو و سبد خرید) +// Guard متغیرهای سراسری // ============================================ -let productsData = []; -let cart = []; +const MOTAYEB_AJAX = (typeof motayeb_ajax !== 'undefined') ? motayeb_ajax : { + ajax_url: '/wp-admin/admin-ajax.php', + nonce: '', + home_url: '/', + checkout_url: '/checkout/', + cart_url: '/cart/' +}; + +// ============================================ +// مدیریت State با localStorage +// ============================================ +let cart = loadFromStorage('motayeb_cart', []); +let wishlist = loadFromStorage('motayeb_wishlist', []); let selectedWeightPrice = 295000; +function loadFromStorage(key, fallback) { + try { + const saved = localStorage.getItem(key); + return saved ? JSON.parse(saved) : fallback; + } catch (e) { + return fallback; + } +} + +function saveToStorage(key, value) { + try { + localStorage.setItem(key, JSON.stringify(value)); + } catch (e) { + // localStorage ممکنه private mode باشه — نادیده می‌گیریم + } +} + +// ============================================ +// ابزارهای کمکی +// ============================================ + +/** + * Escape کردن HTML برای جلوگیری از XSS + */ +function escapeHtml(str) { + if (str === null || str === undefined) return ''; + return String(str) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + +/** + * فرمت قیمت — اعداد فارسی + نمایش رایگان برای قیمت صفر + */ +function formatPrice(n) { + n = Number(n) || 0; + if (n === 0) return 'رایگان'; + return n.toLocaleString('fa-IR'); +} + +/** + * درخواست Ajax با مدیریت خطای کامل + */ +async function motayebFetch(action, params = {}) { + const url = new URL(MOTAYEB_AJAX.ajax_url, window.location.origin); + url.searchParams.set('action', action); + url.searchParams.set('nonce', MOTAYEB_AJAX.nonce); + Object.keys(params).forEach(k => url.searchParams.set(k, params[k])); + + const response = await fetch(url.toString()); + if (!response.ok) { + throw new Error('HTTP ' + response.status); + } + const data = await response.json(); + return data; +} + // ============================================ // توابع سبد خرید // ============================================ -function quickAddToCart(id) { - // اگر محصول در دیتا نبود، از طریق Ajax واکشی کن - fetch(motayeb_ajax.ajax_url + '?action=get_product_data&id=' + id + '&nonce=' + motayeb_ajax.nonce) - .then(response => response.json()) - .then(data => { - if (data.success) { - const p = data.data; - const existing = cart.find(x => x.id === p.id); - if (existing) { existing.qty++; } - else { cart.push({ ...p, qty: 1 }); } - updateCartUI(); - showToast(p.name + ' به سبد خرید اضافه شد', 'success'); + +async function quickAddToCart(id) { + try { + const data = await motayebFetch('get_product_data', { id: id }); + if (data.success) { + const p = data.data; + const existing = cart.find(x => x.id === p.id); + if (existing) { + existing.qty++; + } else { + cart.push({ ...p, qty: 1 }); } - }) - .catch(() => { - // اگر Ajax کار نکرد، از داده‌های mock استفاده کن - const mockProduct = { - id: id, - name: 'محصول شماره ' + id, - price: 100000, - img: 'default-product' - }; - const existing = cart.find(x => x.id === mockProduct.id); - if (existing) { existing.qty++; } - else { cart.push({ ...mockProduct, qty: 1 }); } + saveToStorage('motayeb_cart', cart); updateCartUI(); - showToast(mockProduct.name + ' به سبد خرید اضافه شد', 'success'); - }); + showToast(escapeHtml(p.name) + ' به سبد خرید اضافه شد', 'success'); + } else { + showToast('محصول یافت نشد', 'error'); + } + } catch (err) { + console.error('quickAddToCart:', err); + showToast('خطا در ارتباط با سرور', 'error'); + } } -function addToCartDetail(productId) { - const qty = parseInt(document.getElementById('product-qty')?.textContent || 1); - // از طریق Ajax محصول رو واکشی کن - fetch(motayeb_ajax.ajax_url + '?action=get_product_data&id=' + productId + '&nonce=' + motayeb_ajax.nonce) - .then(response => response.json()) - .then(data => { - if (data.success) { - const p = data.data; - const existing = cart.find(x => x.id === p.id); - if (existing) { existing.qty += qty; } - else { cart.push({ ...p, qty: qty }); } - updateCartUI(); - showToast(p.name + ' به سبد خرید اضافه شد', 'success'); +async function addToCartDetail(productId) { + const qtyEl = document.getElementById('product-qty'); + const qty = parseInt(qtyEl ? qtyEl.textContent : '1') || 1; + + try { + const data = await motayebFetch('get_product_data', { id: productId }); + if (data.success) { + const p = data.data; + const existing = cart.find(x => x.id === p.id); + if (existing) { + existing.qty += qty; + } else { + cart.push({ ...p, qty: qty }); } - }) - .catch(() => { - // Mock - const mockProduct = { - id: productId, - name: 'محصول شماره ' + productId, - price: 100000, - img: 'default-product' - }; - const existing = cart.find(x => x.id === mockProduct.id); - if (existing) { existing.qty += qty; } - else { cart.push({ ...mockProduct, qty: qty }); } + saveToStorage('motayeb_cart', cart); updateCartUI(); - showToast(mockProduct.name + ' به سبد خرید اضافه شد', 'success'); - }); + showToast(escapeHtml(p.name) + ' به سبد خرید اضافه شد', 'success'); + } else { + showToast('محصول یافت نشد', 'error'); + } + } catch (err) { + console.error('addToCartDetail:', err); + showToast('خطا در ارتباط با سرور', 'error'); + } } function removeFromCart(id) { cart = cart.filter(x => x.id !== id); + saveToStorage('motayeb_cart', cart); updateCartUI(); } @@ -78,28 +155,35 @@ function updateCartQty(id, delta) { const item = cart.find(x => x.id === id); if (!item) return; item.qty += delta; - if (item.qty <= 0) { removeFromCart(id); return; } + if (item.qty <= 0) { + removeFromCart(id); + return; + } + saveToStorage('motayeb_cart', cart); updateCartUI(); } function updateCartUI() { const count = cart.reduce((s, i) => s + i.qty, 0); - const total = cart.reduce((s, i) => s + i.price * i.qty, 0); + const total = cart.reduce((s, i) => s + (Number(i.price) || 0) * i.qty, 0); - // Badge + // Badge روی آیکون سبد ['cart-count', 'mobile-cart-count', 'cart-drawer-count'].forEach(id => { const el = document.getElementById(id); - if (el) { - if (id === 'cart-drawer-count') { + if (!el) return; + if (id === 'cart-drawer-count') { + el.textContent = count; + } else { + if (count > 0) { el.textContent = count; + el.classList.remove('hidden'); } else { - if (count > 0) { el.textContent = count; el.classList.remove('hidden'); } - else { el.classList.add('hidden'); } + el.classList.add('hidden'); } } }); - // Drawer items + // محتویات drawer const listEl = document.getElementById('cart-items-list'); const emptyEl = document.getElementById('cart-empty'); const footerEl = document.getElementById('cart-drawer-footer'); @@ -114,30 +198,30 @@ function updateCartUI() { listEl.classList.remove('hidden'); if (emptyEl) emptyEl.classList.add('hidden'); if (footerEl) footerEl.classList.remove('hidden'); - + const totalEl = document.getElementById('cart-drawer-total'); if (totalEl) totalEl.textContent = formatPrice(total) + ' تومان'; listEl.innerHTML = cart.map(i => `
- + ${escapeHtml(i.name)}
-

${i.name}

+

${escapeHtml(i.name)}

${formatPrice(i.price)} تومان
- + ${i.qty} - +
- +
`).join(''); } - // Checkout + // صفحه checkout const checkoutItems = document.getElementById('checkout-items'); if (checkoutItems) { if (cart.length === 0) { @@ -145,12 +229,12 @@ function updateCartUI() { } else { checkoutItems.innerHTML = cart.map(i => `
- + ${escapeHtml(i.name)}
-
${i.name}
+
${escapeHtml(i.name)}
${i.qty} عدد
-
${formatPrice(i.price * i.qty)}
+
${formatPrice(Number(i.price) * i.qty)}
`).join(''); } @@ -161,22 +245,18 @@ function updateCartUI() { } } -function formatPrice(n) { - return n.toLocaleString('fa-IR'); -} +// ============================================ +// توابع UI — جستجو، سبد، منو +// ============================================ -// ============================================ -// توابع UI -// ============================================ function openSearch() { const overlay = document.getElementById('search-overlay'); - if (overlay) { - overlay.classList.remove('hidden'); - setTimeout(() => { - const input = document.getElementById('search-input'); - if (input) input.focus(); - }, 100); - } + if (!overlay) return; + overlay.classList.remove('hidden'); + setTimeout(() => { + const input = document.getElementById('search-input'); + if (input) input.focus(); + }, 100); } function closeSearch() { @@ -210,29 +290,46 @@ function closeMobileMenu() { if (menu) menu.classList.add('hidden'); } -function toggleDark() { - document.documentElement.classList.toggle('dark'); -} - function toggleLang() { showToast('نسخه انگلیسی به زودی اضافه می‌شود', 'info'); } function goToCheckout() { closeCart(); - // هدایت به صفحه تسویه حساب ووکامرس - if (typeof motayeb_ajax !== 'undefined' && motayeb_ajax.checkout_url) { - window.location.href = motayeb_ajax.checkout_url; + if (MOTAYEB_AJAX.checkout_url) { + window.location.href = MOTAYEB_AJAX.checkout_url; } else { - // Fallback: اگر متغیر وجود نداشت، به صفحه سبد خرید برود - window.location.href = '/cart/'; + window.location.href = '/checkout/'; } } // ============================================ -// جستجو +// دارک مود — هماهنگ با PHP body_class // ============================================ -function handleSearch(val) { + +/** + * تغییر حالت تاریک. + * - کلاس dark روی (برای Tailwind dark:) + * - کلاس dark-mode روی (برای CSS variables قدیمی) + * - ذخیره در کوکی (برای خواندن سمت سرور در functions.php) + */ +function toggleDark() { + const html = document.documentElement; + const body = document.body; + const isDark = html.classList.toggle('dark'); + body.classList.toggle('dark-mode', isDark); + + // ذخیره در کوکی — ۱ سال اعتبار + const value = isDark ? 'on' : 'off'; + document.cookie = 'motayeb_darkmode=' + value + + ';path=/;max-age=31536000;SameSite=Lax'; +} + +// ============================================ +// جستجوی زنده +// ============================================ + +async function handleSearch(val) { const results = document.getElementById('search-results'); const suggestions = document.getElementById('search-suggestions'); if (!results) return; @@ -244,71 +341,63 @@ function handleSearch(val) { } if (suggestions) suggestions.classList.add('hidden'); - // ارسال درخواست Ajax برای جستجو - fetch(motayeb_ajax.ajax_url + '?action=search_products&term=' + encodeURIComponent(val) + '&nonce=' + motayeb_ajax.nonce) - .then(response => response.json()) - .then(data => { - if (data.success && data.data.length > 0) { - results.innerHTML = data.data.map(p => ` - - `).join(''); - } else { - results.innerHTML = '

محصولی یافت نشد

'; - } - }) - .catch(() => { - // Mock results - results.innerHTML = '

خطا در جستجو. لطفاً دوباره تلاش کنید.

'; - }); +
${formatPrice(p.price)}
+
+ `; + }).join(''); + } else { + results.innerHTML = '

محصولی یافت نشد

'; + } + } catch (err) { + console.error('handleSearch:', err); + results.innerHTML = '

خطا در جستجو. لطفاً دوباره تلاش کنید.

'; + } } -//زوم تصویر +// ============================================ +// گالری محصول — زوم و تغییر تصویر +// ============================================ + function changeImage(src, btn) { const mainImg = document.getElementById('main-product-img'); if (!mainImg) return; - - // 1. تغییر تصویر اصلی + mainImg.src = src; - - // 2. آپدیت ویژگی‌های ضروری برای زوم و پاپ‌آپ ووکامرس mainImg.setAttribute('data-large_image', src); mainImg.setAttribute('data-src', src); - - // 3. مهمترین بخش برای پاپ‌آپ: آپدیت لینک والد ( اطراف عکس) - // ووکامرس برای باز کردن پاپ‌آپ از روی href این لینک استفاده می‌کند - const parentLink = mainImg.closest('a'); - if (parentLink) { - parentLink.href = src; - } - // 4. بروزرسانی کلاس فعال روی thumbnails + const parentLink = mainImg.closest('a'); + if (parentLink) parentLink.href = src; + document.querySelectorAll('.gallery-thumb').forEach(t => t.classList.remove('active')); if (btn) btn.classList.add('active'); - - // 5. بازسازی مجدد Zoom (با متد مقاوم‌تر) + + // بازسازی زوم ووکامرس (اگه jQuery لود شده باشه) if (typeof jQuery !== 'undefined' && typeof jQuery.fn.zoom !== 'undefined') { const $mainImg = jQuery(mainImg); - // والد بلافصل عکس را هدف قرار میدهیم (معمولاً یک
یا است) - const $wrapper = $mainImg.parent(); - - // اگر والد قبلاً زوم داشته باشد، آن را نابود کن + const $wrapper = $mainImg.parent(); $wrapper.trigger('zoom.destroy'); - - // زوم جدید را روی والد اعمال کن - $wrapper.zoom({ - url: src, - touch: false - }); + $wrapper.zoom({ url: src, touch: false }); } } +// ============================================ +// صفحه محصول — انتخاب وزن و تعداد +// ============================================ + function selectWeight(btn, price) { document.querySelectorAll('.weight-btn').forEach(b => { b.classList.remove('active', 'border-forest-500', 'dark:border-forest-300', 'bg-forest-50', 'dark:bg-forest-900/30', 'text-forest-500', 'dark:text-forest-300'); @@ -345,36 +434,60 @@ function switchTab(tabId, btn) { } // ============================================ -// علاقه‌مندی‌ها +// علاقه‌مندی‌ها — با persist در localStorage // ============================================ -function toggleWishlist(btn) { + +function toggleWishlist(btn, productId) { + if (!btn) return; const icon = btn.querySelector('iconify-icon'); if (!icon) return; - const currentIcon = icon.getAttribute('icon'); - if (currentIcon === 'lucide:heart') { + + productId = productId || parseInt(btn.getAttribute('data-product-id')) || 0; + + const index = wishlist.indexOf(productId); + if (index === -1) { + // افزودن به علاقه‌مندی‌ها + wishlist.push(productId); icon.setAttribute('icon', 'lucide:heart'); icon.style.color = '#ef4444'; icon.style.fill = '#ef4444'; - showToast('به علاقه‌مندی‌ها اضافه شد', 'info'); + showToast('به علاقه‌مندی‌ها اضافه شد', 'success'); } else { + // حذف از علاقه‌مندی‌ها + wishlist.splice(index, 1); + icon.setAttribute('icon', 'lucide:heart'); icon.style.color = ''; icon.style.fill = ''; showToast('از علاقه‌مندی‌ها حذف شد', 'info'); } + saveToStorage('motayeb_wishlist', wishlist); } // ============================================ -// Toast +// Toast نوتیفیکیشن // ============================================ -function showToast(msg, type = 'info') { + +function showToast(msg, type) { + type = type || 'info'; const container = document.getElementById('toast-container'); if (!container) return; - const colors = { success: 'bg-forest-500', info: 'bg-earth-400', error: 'bg-red-500' }; - const icons = { success: 'lucide:check-circle', info: 'lucide:info', error: 'lucide:alert-circle' }; + + const colors = { + success: 'bg-forest-500', + info: 'bg-earth-400', + error: 'bg-red-500' + }; + const icons = { + success: 'lucide:check-circle', + info: 'lucide:info', + error: 'lucide:alert-circle' + }; + const toast = document.createElement('div'); - toast.className = `toast flex items-center gap-3 px-5 py-3 ${colors[type] || 'bg-earth-400'} text-white rounded-2xl shadow-xl text-sm font-medium`; - toast.innerHTML = `${msg}`; + toast.className = 'toast flex items-center gap-3 px-5 py-3 ' + (colors[type] || 'bg-earth-400') + ' text-white rounded-2xl shadow-xl text-sm font-medium'; + toast.innerHTML = '' + escapeHtml(msg) + ''; container.appendChild(toast); + setTimeout(() => { toast.style.opacity = '0'; toast.style.transition = 'opacity 0.3s'; @@ -385,30 +498,92 @@ function showToast(msg, type = 'info') { // ============================================ // فرم‌ها // ============================================ + function handleNewsletter(e) { e.preventDefault(); const email = document.getElementById('newsletter-email'); - if (email) { + if (email && email.value) { showToast(email.value + ' با موفقیت ثبت شد!', 'success'); email.value = ''; } + return false; } function handleContact(e) { e.preventDefault(); showToast('پیام شما با موفقیت ارسال شد. به زودی پاسخ می‌دهیم.', 'success'); e.target.reset(); + return false; +} + +// ============================================ +// سیستم امتیازدهی ستاره‌ای +// ============================================ + +let currentRating = 0; + +/** + * تعیین امتیاز با کلیک روی ستاره + */ +function setRating(rating) { + currentRating = rating; + renderStars(rating); + + // تنظیم فیلد مخفی برای ارسال با فرم + const hiddenInput = document.getElementById('rating-input'); + if (hiddenInput) hiddenInput.value = rating; +} + +/** + * نمایش ستاره‌ها با امتیاز داده‌شده + * @param {number} rating - امتیاز از ۱ تا ۵ + * @param {string} containerId - شناسه ظرف (پیش‌فرض: star-rating) + */ +function renderStars(rating, containerId) { + containerId = containerId || 'star-rating'; + const container = document.getElementById(containerId); + if (!container) return; + + container.innerHTML = ''; + + for (let i = 1; i <= 5; i++) { + const star = document.createElement('i'); + if (i <= rating) { + // ستاره پر — طلایی (کلاس‌های Tailwind/FontAwesome) + star.className = 'fa-solid fa-star text-honey-400 cursor-pointer transition'; + } else { + // ستاره خالی — خاکستری + star.className = 'fa-regular fa-star text-cream-300 dark:text-dark-muted cursor-pointer transition'; + } + star.dataset.rating = i; + star.setAttribute('role', 'button'); + star.setAttribute('aria-label', 'امتیاز ' + i + ' از ۵'); + star.addEventListener('click', function() { + setRating(parseInt(this.dataset.rating)); + }); + star.addEventListener('mouseenter', function() { + renderStars(parseInt(this.dataset.rating), containerId); + }); + container.appendChild(star); + } + + // وقتی موس از ظرف خارج شد، به امتیاز فعلی برگرد + container.onmouseleave = function() { + renderStars(currentRating, containerId); + }; } // ============================================ // رویدادهای صفحه کلید // ============================================ + document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { closeSearch(); closeCart(); closeMobileMenu(); } + // Ctrl/Cmd + K برای باز کردن جستجو if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); openSearch(); @@ -418,64 +593,81 @@ document.addEventListener('keydown', function(e) { // ============================================ // تغییر هدر هنگام اسکرول // ============================================ -let lastScroll = 0; + window.addEventListener('scroll', function() { const header = document.getElementById('header'); if (!header) return; - const scroll = window.scrollY; - if (scroll > 100) { + if (window.scrollY > 100) { header.classList.add('shadow-lg'); } else { header.classList.remove('shadow-lg'); } - lastScroll = scroll; -}); +}, { passive: true }); // ============================================ -// مقداردهی اولیه +// مقداردهی اولیه — همه در یک listener // ============================================ + document.addEventListener('DOMContentLoaded', function() { - // تنظیم شمارنده سبد خرید از کوکی (اختیاری) + // ۱. به‌روزرسانی UI سبد خرید از localStorage updateCartUI(); - - // اگر در صفحه محصول هستیم، کلاس‌های گالری رو تنظیم کن + + // ۲. تنظیم گالری محصول (اگه در صفحه محصول هستیم) const mainImg = document.getElementById('main-product-img'); if (mainImg) { - // اولین تصویر گالری رو به‌عنوان active تنظیم کن const firstThumb = document.querySelector('.gallery-thumb'); if (firstThumb) firstThumb.classList.add('active'); } + + // ۳. رندر ستاره‌های امتیازدهی (اگه ظرف وجود داشته باشه) + const starContainer = document.getElementById('star-rating'); + if (starContainer) { + // خواندن امتیاز فعلی از فیلد مخفی (اگه ویرایش نظر باشه) + const hiddenInput = document.getElementById('rating-input'); + currentRating = hiddenInput ? parseInt(hiddenInput.value) || 0 : 0; + renderStars(currentRating); + } + + // ۴. علامت‌گذاری آیکون‌های علاقه‌مندی که قبلاً انتخاب شده‌ان + document.querySelectorAll('[data-wishlist-btn]').forEach(btn => { + const productId = parseInt(btn.getAttribute('data-product-id')) || 0; + if (wishlist.indexOf(productId) !== -1) { + const icon = btn.querySelector('iconify-icon'); + if (icon) { + icon.style.color = '#ef4444'; + icon.style.fill = '#ef4444'; + } + } + }); }); -// نمونه کد جایگزین برای تولید ستاره -function renderStars(rating) { - // ⚠️ اینجا را تغییر دهید: به جای 'ستاره_کانتینر_آیدی'، شناسه واقعی تگ div در HTML خود را بگذارید - const container = document.getElementById('star-rating'); // یا هر شناسه‌ای که در HTML دارید - if (!container) return; // اگر ظرف پیدا نشد، کد متوقف شود تا خطا ندهد - - container.innerHTML = ''; // پاک کردن ظرف - - for (let i = 1; i <= 5; i++) { - let star = document.createElement('i'); // ساختن تگ آیکون - if (i <= rating) { - star.className = 'fa-solid fa-star text-warning'; // ستاره پر طلایی - } else { - star.className = 'fa-regular fa-star text-secondary'; // ستاره خالی خاکستری - } - // اضافه کردن کلیک برای ثبت نظر - star.onclick = function() { setRating(i); }; - - container.appendChild(star); - } -} - +// AJAX Add to Cart برای صفحه محصول document.addEventListener('DOMContentLoaded', function() { - // فرض کنید امتیاز فعلی محصول 0 است یا از دیتابیس می‌خوانید - let initialRating = 0; // یا عددی که از سمت سرور به جاوا اسکریپت پاس داده می‌شود - - // اگر در صفحه جزئیات نظر هستیم، تابع ستاره‌ها را صدا بزنیم - const starContainer = document.getElementById('star-rating'); // همان شناسه بالا - if (starContainer) { - renderStars(initialRating); - } + var form = document.querySelector('form.cart'); + if (!form) return; + + form.addEventListener('submit', function(e) { + e.preventDefault(); + var formData = new FormData(form); + var productId = formData.get('add-to-cart'); + var quantity = formData.get('quantity') || 1; + + fetch(MOTAYEB_AJAX.ajax_url, { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: 'action=woocommerce_add_to_cart&product_id=' + productId + '&quantity=' + quantity + }) + .then(r => r.json()) + .then(data => { + if (data.fragments) { + // به‌روزرسانی fragment های ووکامرس (مثل شمارنده سبد) + Object.keys(data.fragments).forEach(function(key) { + var el = document.querySelector(key); + if (el) el.innerHTML = data.fragments[key]; + }); + showToast('به سبد خرید اضافه شد', 'success'); + } + }) + .catch(err => showToast('خطا در افزودن', 'error')); + }); }); \ No newline at end of file diff --git a/footer.php b/footer.php index 6fe454a..05165be 100644 --- a/footer.php +++ b/footer.php @@ -3,12 +3,88 @@ * فوتر سایت - مطابق با UI Kolli.html * * @package Motayeb + * @version 1.0.1 + * + * تغییرات نسخه ۱.۰.۱: + * - guard کامل WooCommerce (بدون fatal error اگه غیرفعال باشه) + * - transient cache برای دسته‌بندی‌های فوتر + * - نمایش لینک فعال (active) در ناوبری موبایل بر اساس صفحه جاری + * - آیکون/رنگ دسته‌بندی از term meta (هماهنگ با front-page.php) + * - شماره تماس/ایمیل/آدرس از تنظیمات تم + * - aria-label روی همه بخش‌ها + * - Schema.org Footer Schema + * - دکمه Scroll to Top + * - رفع فضای اضافه در کلاس باتن موبایل + * - نماد اعتماد و ساماندهی به لینک‌های واقعی */ + +// تعیین آدرس فروشگاه — با guard ووکامرس + $footer_shop_url = ( function_exists( 'wc_get_page_id' ) && wc_get_page_id( 'shop' ) > 0 ) + ? get_permalink( wc_get_page_id( 'shop' ) ) + : home_url( '/shop' ); + +// تشخیص صفحه جاری برای active state ناوبری موبایل + $current_url = home_url( add_query_arg( null, null ) ); + $is_home = is_front_page() && is_home(); + $is_shop_page = ( function_exists( 'is_shop' ) && is_shop() ) || ( function_exists( 'is_product_category' ) && is_product_category() ); + $is_cart_or_checkout = ( function_exists( 'is_cart' ) && is_cart() ) || ( function_exists( 'is_checkout' ) && is_checkout() ); + $is_account = ( function_exists( 'is_account_page' ) && is_account_page() ); + +// خواندن تنظیمات تم + $footer_phone = get_option( 'motayeb_contact_phone', '021-12345678' ); + $footer_email = get_option( 'motayeb_contact_email', get_option( 'admin_email' ) ); + $footer_address = get_option( 'motayeb_contact_address', 'تهران، ایران' ); + $footer_instagram = get_option( 'motayeb_social_instagram', '' ); + $footer_telegram = get_option( 'motayeb_social_telegram', '' ); + $footer_twitter = get_option( 'motayeb_social_twitter', '' ); + $samandehi_url = get_option( 'motayeb_samandehi_url', '' ); + $enamad_url = get_option( 'motayeb_enamad_url', '' ); + +// لینک‌های خدمات مشتریان از صفحات وردپرس + $faq_page_id = get_option( 'motayeb_page_faq', 0 ); + $return_page_id = get_option( 'motayeb_page_return', 0 ); + $shipping_page_id = get_option( 'motayeb_page_shipping', 0 ); + $privacy_page_id = get_option( 'motayeb_page_privacy', 0 ); + $terms_page_id = get_option( 'motayeb_page_terms', 0 ); + $about_page_id = get_option( 'motayeb_page_about', 0 ); + $contact_page_id = get_option( 'motayeb_page_contact', 0 ); + +// تبدیل ID صفحه به URL (با fallback) +function motayeb_page_url( $page_id, $fallback = '#' ) { + if ( $page_id && get_post( $page_id ) ) { + return get_permalink( $page_id ); + } + return $fallback; +} + +// دسته‌بندی‌های فوتر با cache + $footer_cats_cache_key = 'motayeb_footer_categories'; + $footer_cats = get_transient( $footer_cats_cache_key ); +if ( false === $footer_cats ) { + $footer_cats = get_terms( array( + 'taxonomy' => 'product_cat', + 'hide_empty' => false, + 'parent' => 0, + 'number' => 5, + 'orderby' => 'count', + 'order' => 'DESC', + ) ); + if ( ! is_wp_error( $footer_cats ) ) { + set_transient( $footer_cats_cache_key, $footer_cats, DAY_IN_SECONDS ); + } +} ?> + + + -
+ -
+
+ + -
+
+ + -
+
+
+
-

© مطیب. تمامی حقوق محفوظ است.

+

© مطیب. تمامی حقوق محفوظ است.

-
نماد اعتماد
-
ساماندهی
+ + + + نماد اعتماد + + + + + + ساماندهی + +
-