- Introduced `TranslatableName` module to allow for localized names for `Country` and `Region` models. - Updated views to display `localized_name` instead of `name` for improved internationalization. - Refactored JSON serialization for `translations` attribute. - Enhanced localization support by adding new languages: Japanese and Korean, with updated locale files. - Removed outdated English and Chinese locales for countries and regions to clean up the codebase.
172 lines
8.0 KiB
Plaintext
172 lines
8.0 KiB
Plaintext
<!-- app/views/arts/index.html.erb -->
|
|
<div class="min-h-screen">
|
|
<!-- 页面标题和背景 -->
|
|
<% featured_art = @weather_arts.first %>
|
|
<div class="relative">
|
|
<!-- 背景图像 -->
|
|
<% if featured_art&.image&.attached? %>
|
|
<div class="absolute inset-0 h-[40vh] overflow-hidden">
|
|
<%= image_tag featured_art.webp_image.processed,
|
|
class: "w-full h-full object-cover" %>
|
|
<div class="absolute inset-0 bg-gradient-to-b from-base-100/30 via-base-100/60 to-base-100"></div>
|
|
</div>
|
|
<% end %>
|
|
|
|
<!-- 标题内容 -->
|
|
<div class="relative pt-20 pb-32">
|
|
<div class="container mx-auto px-4">
|
|
<div class="max-w-3xl mx-auto text-center space-y-6">
|
|
<h1 class="text-4xl md:text-5xl font-display font-bold">
|
|
<%= t("arts.title") %>
|
|
</h1>
|
|
<p class="text-xl text-base-content/70">
|
|
<%= t("arts.subtitle") %>
|
|
</p>
|
|
|
|
<!-- 如果有特色图片,显示其信息 -->
|
|
<% if featured_art %>
|
|
<div class="text-sm text-base-content/60 pt-4">
|
|
<%= "#{t("text.latest_from")} #{featured_art.city.full_name}" %>
|
|
<span class="mx-2">•</span>
|
|
<%= featured_art.formatted_time(:date) %>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 筛选导航 -->
|
|
<div class="container mx-auto px-4 -mt-8">
|
|
<div class="bg-base-100 shadow-xl rounded-box p-6 mb-12">
|
|
<!-- 筛选选项 -->
|
|
<div class="flex flex-wrap gap-4 justify-center items-center">
|
|
<!-- 时间排序 -->
|
|
<div class="dropdown">
|
|
<button class="btn btn-ghost gap-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
<%= params[:sort] == 'oldest' ? t("text.oldest_first") : t("text.newest_first") %>
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
|
</svg>
|
|
</button>
|
|
<ul class="dropdown-content z-[1] menu p-2 shadow-lg bg-base-100 rounded-box w-52">
|
|
<li>
|
|
<%= link_to t("text.newest_first"), arts_path(sort: 'newest', region: params[:region]),
|
|
class: "#{'active' if params[:sort] != 'oldest'}" %>
|
|
</li>
|
|
<li>
|
|
<%= link_to t("text.oldest_first"), arts_path(sort: 'oldest', region: params[:region]),
|
|
class: "#{'active' if params[:sort] == 'oldest'}" %>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- 区域筛选 -->
|
|
<div class="dropdown">
|
|
<button class="btn btn-ghost gap-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
<%= @current_region&.localized_name || t("text.all_regions") %>
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
|
</svg>
|
|
</button>
|
|
<ul class="dropdown-content z-[1] menu p-2 shadow-lg bg-base-100 rounded-box w-52">
|
|
<li>
|
|
<%= link_to t("text.all_regions"), arts_path(sort: params[:sort]),
|
|
class: "#{'active' unless @current_region}" %>
|
|
</li>
|
|
<div class="divider my-1"></div>
|
|
<% @regions.each do |region| %>
|
|
<li>
|
|
<%= link_to region.localized_name, arts_path(region: region.id, sort: params[:sort]),
|
|
class: "#{'active' if @current_region == region}" %>
|
|
</li>
|
|
<% end %>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 结果统计 -->
|
|
<div class="text-center text-sm text-base-content/70 mt-4">
|
|
<%= "#{t("text.showing")} #{@weather_arts.total_count} #{t("text.weather_arts")} " %>
|
|
<% if @current_region %>
|
|
from <%= @current_region.localized_name %>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="container mx-auto px-4 pb-16">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
|
<% @weather_arts.each do |art| %>
|
|
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-all duration-300 group overflow-hidden">
|
|
<figure class="relative aspect-square overflow-hidden">
|
|
<% if art.image.attached? %>
|
|
<%= image_tag art.preview_image.processed,
|
|
class: "w-full h-full object-cover transform group-hover:scale-105 transition-transform duration-500" %>
|
|
|
|
<div class="absolute inset-0 bg-gradient-to-t from-black via-black/50 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
|
|
|
<div class="absolute inset-0 p-6 flex flex-col justify-end translate-y-4 opacity-0 group-hover:translate-y-0 group-hover:opacity-100 transition-all duration-300">
|
|
<div class="text-white space-y-2">
|
|
<h3 class="text-xl font-display font-bold">
|
|
<%= art.city.name %>
|
|
</h3>
|
|
<p class="text-sm text-white/80">
|
|
<%= "#{art.city&.country&.emoji + " " || ""}#{art.city&.country&.localized_name}" %>
|
|
</p>
|
|
<div class="flex items-center gap-2 text-white/90">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z" />
|
|
</svg>
|
|
<%= art.description %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
</figure>
|
|
|
|
<!-- 信息部分 -->
|
|
<div class="card-body p-4">
|
|
<div class="flex justify-between items-start mb-3">
|
|
<div>
|
|
<h3 class="font-display font-bold leading-tight">
|
|
<%= art.city.name %>
|
|
</h3>
|
|
<p class="text-sm text-base-content/70">
|
|
<%= art.formatted_time(:date, true) %>
|
|
</p>
|
|
</div>
|
|
<div class="text-right">
|
|
<div class="text-2xl font-bold text-primary">
|
|
<%= art.temperature %>°C
|
|
</div>
|
|
<div class="text-sm text-base-content/70">
|
|
<%= art.humidity %>% humidity
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<%= link_to city_weather_art_path(art.city, art),
|
|
class: "btn btn-primary btn-sm w-full" do %>
|
|
<%= t("button.view_detail") %>
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3" />
|
|
</svg>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
|
|
<%= render 'shared/pagination',
|
|
collection: @weather_arts,
|
|
collection_name: 'weather arts' %>
|
|
</div>
|
|
</div>
|
|
</div> |