File size: 9,604 Bytes
4bea261
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
---
import Layout from '../layouts/Layout.astro';
import { formatImageUrl } from '../lib/api.js';
import { txasupabase } from '../lib/txasupabase.js';

// Lấy tất cả phim có lịch chiếu tập tiếp theo
let scheduledMovies = [];
try {
  const localMovies = await txasupabase.getLocalMovies().catch(() => ({}));
  scheduledMovies = Object.entries(localMovies)
    .map(([slug, m]) => {
      if (!m || !m.movie) return null;
      return {
        ...m.movie,
        slug
      };
    })
    .filter(Boolean)
    .filter(movie => movie.next_episode_time)
    .filter(movie => {
      const nextTime = new Date(movie.next_episode_time);
      const minTime = new Date(Date.now() - 7 * 86400000);
      return nextTime >= minTime;
    })
    .sort((a, b) => new Date(a.next_episode_time).getTime() - new Date(b.next_episode_time).getTime());
} catch (e) {
  console.error('[lich-chieu] Error fetching schedule:', e);
}

// Nhóm phim theo ngày
const getVietnamDateString = (date) => {
  return new Date(date).toLocaleDateString('en-CA', { timeZone: 'Asia/Ho_Chi_Minh' });
};

const today = new Date(new Date().toLocaleDateString('en-US', { timeZone: 'Asia/Ho_Chi_Minh' }));
today.setHours(0, 0, 0, 0);

// Tạo danh sách 7 ngày từ hôm nay
const days = [];
for (let i = 0; i < 7; i++) {
  const d = new Date(today);
  d.setDate(d.getDate() + i);
  days.push(d);
}

const dayNames = ['Chủ Nhật', 'Thứ Hai', 'Thứ Ba', 'Thứ Tư', 'Thứ Năm', 'Thứ Sáu', 'Thứ Bảy'];

function getMoviesForDate(date: Date) {
  const targetStr = getVietnamDateString(date);
  return scheduledMovies.filter(m => {
    return getVietnamDateString(m.next_episode_time) === targetStr;
  });
}
---

<Layout title="Lịch chiếu phim - Lịch phát sóng tập mới" description="Xem lịch chiếu phim, lịch phát sóng tập mới nhất hàng ngày tại DPTXA." slug="/lich-chieu">
  <div class="min-h-screen pb-24">
    <div class="mx-auto max-w-7xl px-4">
      
      <!-- Header -->
      <div class="mb-8">
        <div class="flex items-center gap-3 text-[10px] font-black uppercase tracking-widest text-gray-500 mb-4">
          <a href="/" class="hover:text-primary transition-colors">Trang chủ</a>
          <i class="fas fa-chevron-right text-[8px] opacity-30"></i>
          <span class="text-primary">Lịch chiếu</span>
        </div>
        <h1 class="text-3xl font-black text-white tracking-tight flex items-center gap-3">
          <i class="fas fa-calendar-alt text-primary"></i> Lịch chiếu
        </h1>
      </div>

      <!-- Date Tabs -->
      <div class="relative mb-8">
        <div id="date-tabs" class="flex items-center gap-2 overflow-x-auto pb-2 scrollbar-thin">
          {days.map((d, i) => {
            const dd = String(d.getDate()).padStart(2, '0');
            const mm = String(d.getMonth() + 1).padStart(2, '0');
            const dayName = dayNames[d.getDay()];
            const isToday = i === 0;
            const count = getMoviesForDate(d).length;
            return (
              <button 
                data-tab-index={i}
                class={`schedule-tab flex flex-col items-center shrink-0 px-6 py-3 rounded-2xl border transition-all cursor-pointer ${
                  isToday 
                    ? 'bg-primary/15 border-primary/30 text-primary' 
                    : 'bg-white/[0.03] border-white/[0.06] text-gray-400 hover:bg-white/5 hover:text-white'
                }`}
              >
                <span class="text-[10px] font-bold text-gray-500">{dd}/{mm}</span>
                <span class={`text-sm font-black ${isToday ? 'text-primary' : ''}`}>{dayName}</span>
                {count > 0 && (
                  <span class="mt-1 text-[9px] font-bold bg-primary/20 text-primary px-2 py-0.5 rounded-full">{count} phim</span>
                )}
              </button>
            );
          })}
        </div>
      </div>

      <!-- Movie Lists per Day -->
      {days.map((d, i) => {
        const moviesForDay = getMoviesForDate(d);
        return (
          <div data-panel-index={i} class={`schedule-panel ${i === 0 ? '' : 'hidden'}`}>
            {moviesForDay.length === 0 ? (
              <div class="text-center py-24 glass rounded-[32px] border border-white/5 p-8 relative overflow-hidden">
                <div class="absolute -right-20 -top-20 h-40 w-40 rounded-full bg-white/[0.01] blur-3xl"></div>
                <div class="h-16 w-16 rounded-2xl bg-white/[0.03] border border-white/5 flex items-center justify-center mx-auto mb-4 text-gray-600 shadow-inner">
                  <i class="far fa-calendar-times text-2xl"></i>
                </div>
                <p class="text-gray-400 text-sm font-bold tracking-tight">Không có phim nào dự kiến phát sóng vào ngày này.</p>
                <p class="text-xs text-gray-600 mt-1">Đón xem các cập nhật mới nhất từ ban quản trị hệ thống.</p>
              </div>
            ) : (
              <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                {moviesForDay.map(m => {
                  const poster = formatImageUrl(m.poster_url || m.thumb_url);
                  const epLabel = m.next_episode_name || m.episode_current || 'Tập mới';
                  const timeStr = new Date(m.next_episode_time).toLocaleTimeString('vi-VN', { hour: '2-digit', minute: '2-digit', hour12: false, timeZone: 'Asia/Ho_Chi_Minh' });
                  return (
                    <a href={`/phim/${m.slug}`} class="relative flex items-center gap-4 rounded-3xl bg-gradient-to-br from-white/[0.03] to-white/[0.01] border border-white/5 p-4 hover:bg-white/[0.06] hover:border-primary/30 transition-all duration-300 group shadow-lg overflow-hidden">
                      <!-- Ambient Glow -->
                      <div class="absolute -right-8 -bottom-8 h-24 w-24 rounded-full bg-primary/5 blur-2xl group-hover:bg-primary/10 transition-colors duration-300"></div>
                      
                      <!-- Movie Thumbnail -->
                      <div class="h-20 w-16 rounded-2xl overflow-hidden shrink-0 border border-white/10 shadow-md relative">
                        <img src={poster} alt={m.name} class="h-full w-full object-cover group-hover:scale-110 transition-transform duration-500" loading="lazy" />
                        <div class="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent"></div>
                      </div>
                      
                      <!-- Movie Meta -->
                      <div class="min-w-0 flex-1 space-y-1">
                        <span class="inline-flex items-center gap-1.5 text-[9px] font-black uppercase tracking-wider text-gray-500">
                          <span class="h-1.5 w-1.5 rounded-full bg-primary animate-pulse"></span>
                          Sắp phát sóng
                        </span>
                        <div class="text-sm font-black text-white truncate group-hover:text-primary transition-colors duration-300">{m.name}</div>
                        
                        <div class="flex items-center gap-2 mt-1.5">
                          <span class="text-[10px] font-black bg-primary/10 border border-primary/20 text-primary px-2.5 py-1 rounded-xl flex items-center gap-1">
                            <i class="far fa-clock"></i>
                            {timeStr}
                          </span>
                          <span class="text-[10px] font-bold text-gray-400">
                            {epLabel}
                          </span>
                        </div>
                      </div>
                      
                      <!-- Action Icon -->
                      <div class="h-8 w-8 rounded-full bg-white/[0.03] border border-white/5 flex items-center justify-center shrink-0 group-hover:bg-primary/20 group-hover:border-primary/30 transition-all duration-300 text-gray-500 group-hover:text-primary shadow-inner">
                        <i class="fas fa-chevron-right text-xs group-hover:translate-x-0.5 transition-transform"></i>
                      </div>
                    </a>
                  );
                })}
              </div>
            )}
          </div>
        );
      })}

    </div>
  </div>
</Layout>

<script>
  document.addEventListener('astro:page-load', () => {
    const tabs = document.querySelectorAll('.schedule-tab');
    const panels = document.querySelectorAll('.schedule-panel');
    
    tabs.forEach(tab => {
      tab.addEventListener('click', () => {
        const idx = tab.getAttribute('data-tab-index');
        
        // Reset all tabs
        tabs.forEach(t => {
          t.classList.remove('bg-primary/15', 'border-primary/30', 'text-primary');
          t.classList.add('bg-white/[0.03]', 'border-white/[0.06]', 'text-gray-400');
          const nameSpan = t.querySelector('.text-sm');
          if (nameSpan) nameSpan.classList.remove('text-primary');
        });
        
        // Activate clicked tab
        tab.classList.add('bg-primary/15', 'border-primary/30', 'text-primary');
        tab.classList.remove('bg-white/[0.03]', 'border-white/[0.06]', 'text-gray-400');
        const nameSpan = tab.querySelector('.text-sm');
        if (nameSpan) nameSpan.classList.add('text-primary');
        
        // Show/hide panels
        panels.forEach(p => {
          if (p.getAttribute('data-panel-index') === idx) {
            p.classList.remove('hidden');
          } else {
            p.classList.add('hidden');
          }
        });
      });
    });
  });
</script>