PageSourceSearch

https://samurai.ru/local/templates/new_design/components_vue/CatchMomentBanner/index.js

js samurai.ru collected 2026-10-01 23:56:03 UTC 6,942 bytes, 182 lines download raw bytes

1const mapGetters = Vuex.mapGetters;
2const mapActions = Vuex.mapActions;
3export default {
4    name: "CatchMomemtBanner",
5    template: /* html */ `
6        <div class="banner-container" v-if="catchMomentData.product">
7            <div class="moment-block banner-item">
8                <div class="moment-header">
9                    <span class="header-text">{{ catchMomentData.header }}</span>
10                </div>
11                
12                <div class="time-display">
13                    <div class="time-section">
14                        <div class="numbers-container">
15                            <div class="number-item">{{ formattedTime.hours.first_num }}</div>
16                            <div class="number-item">{{ formattedTime.hours.second_num }}</div>
17                        </div>
18                        <div class="units">часов</div>
19                    </div>
20
21                    <div class="colon">:</div>
22
23                    <div class="time-section">
24                        <div class="numbers-container">
25                            <div class="number-item">{{ formattedTime.minutes.first_num }}</div>
26                            <div class="number-item">{{ formattedTime.minutes.second_num }}</div>
27                        </div>
28                        <div class="units">минут</div>
29                    </div>
30                    
31                    <div class="colon">:</div>
32                    
33                    <div class="time-section">
34                        <div class="numbers-container">
35                            <div class="number-item">{{ formattedTime.seconds.first_num }}</div>
36                            <div class="number-item">{{ formattedTime.seconds.second_num }}</div>
37                        </div>
38                        <div class="units">секунд</div>
39                    </div>
40                </div>
41            </div>
42
43            <div class="promo-info banner-item">
44                <div class="promo-info-container">
45                    <div class="top-info">
46                        <div class="product-name">
47                            {{ catchMomentData.product.name }}
48                        </div>
49                        <div class="product-weight">
50                            {{ catchMomentData.product.property_item_weight_value }}
51                        </div>
52                    </div>
53                    <div class="bottom-info">
54                        <div class="prices-block">
55                            <div class="basket-card_price-new">
56                                <span v-html="catchMomentData.new_price"></span> ₽ 
57                            </div>
58                            <div class="basket-card_price-old">
59                                <span v-html="catchMomentData.product.price"></span> ₽ 
60                            </div>
61                        </div>
62                        <button class="button dark" @click="addProductInBasket(catchMomentData.product)">
63                            Добавить
64                        </button>
65                    </div>
66                </div>
67            </div>
68            <div class="product-img banner-item">
69                <img class="banner-img" :src="catchMomentData.product.detail_picture">
70            </div>
71        </div>
72    `,
73    data() {
74        return {
75            timeLeft: 0, // в секундах
76            timerInterval: null
77        };
78    },
79    computed: {
80        ...mapGetters({
81            catchMomentData: "GET_CATCH_MOMENT_DATA"
82        }),
83
84        formattedTime() {
85            const totalSeconds = this.timeLeft;
86            
87            // Вычисляем часы, минуты, секунды
88            const hours = Math.floor(totalSeconds / 3600);
89            const minutes = Math.floor((totalSeconds % 3600) / 60);
90            const seconds = totalSeconds % 60;
91            
92            // Функция для разделения числа на две цифры
93            const splitNumber = (num) => {
94                const str = num.toString().padStart(2, '0');
95                return {
96                    first_num: parseInt(str[0]), // первая цифра (десятки)
97                    second_num: parseInt(str[1])  // вторая цифра (единицы)
98                };
99            };
100
101            return {
102                hours: splitNumber(hours),
103                minutes: splitNumber(minutes),
104                seconds: splitNumber(seconds)
105            };
106        }
107    },
108    methods: {
109        ...mapActions([
110            "addProductInBasket",
111        ]),
112
113        // Запуск таймера
114        startTimer() {
115            if (!this.catchMomentData?.end) {
116                return;
117            }
118
119            // Первоначальный расчет
120            this.updateTimeLeft();
121            
122            // Запускаем интервал обновления каждую секунду
123            this.timerInterval = setInterval(() => {
124                this.updateTimeLeft();
125            }, 1000);
126        },
127
128        // Обновление оставшегося времени
129        updateTimeLeft() {
130            if (!this.catchMomentData?.end) return;
131            
132            const now = Math.floor(Date.now() / 1000); // текущее время в секундах
133            const endTime = this.catchMomentData.end; // время окончания в секундах
134            
135            const diff = Math.max(0, endTime - now);
136
137            this.timeLeft = diff;
138
139            // Если время вышло, останавливаем таймер
140            if (diff <= 0) {
141                this.stopTimer();
142            }
143        },
144
145        // Остановка таймера
146        stopTimer() {
147            if (this.timerInterval) {
148                clearInterval(this.timerInterval);
149                this.timerInterval = null;
150            }
151        },
152
153        // Добавление нуля для чисел < 10
154        padTime(time) {
155            return time.toString().padStart(2, '0');
156        },
157        
158        // Покупка товара
159        buyProduct() {
160            console.log('Клик на кнопку покупки');
161            // Добавь свою логику покупки
162        }
163    },
164    watch: {
165        // Запускаем таймер когда данные загрузились
166        catchMomentData: {
167            handler(newData) {
168                if (newData?.end) {
169                    this.stopTimer(); // Останавливаем старый таймер
170                    this.$nextTick(() => {
171                        this.startTimer(); // Запускаем новый
172                    });
173                }
174            },
175            immediate: true,
176            deep: true
177        }
178    },
179    beforeUnmount() {
180        this.stopTimer();
181    }
182};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.