This commit is contained in:
root
2026-06-07 23:18:53 +08:00
parent ebd3d6a317
commit 934b9a4a23
36 changed files with 2272 additions and 296 deletions

View File

@@ -6,6 +6,7 @@ import { useTranslation } from "@/i18n/navigation";
import { Link } from "@/i18n/navigation";
import { City } from "@/app/data/cities";
import { apiFetch } from "@/app/lib/api-client";
import { mediaUrl } from "@/app/lib/media";
const CITY_COORDS: Record<string, [number, number]> = {
: [25.7, 100.2],
@@ -152,7 +153,7 @@ export default function CityModal({ city, isOpen, onClose }: CityModalProps) {
<div className="relative h-36 sm:h-44 md:h-52 shrink-0">
{typeof coverImage === "string" && coverImage.startsWith("http") ? (
<img
src={coverImage}
src={mediaUrl(coverImage)}
alt={city.name}
className="absolute inset-0 w-full h-full object-cover"
/>
@@ -470,7 +471,7 @@ function CityTabContent({
return (
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
{photos.map((src) => (
<img key={src} src={src} alt={city.name} className="h-56 w-full rounded-2xl object-cover shadow-sm" />
<img key={src} src={mediaUrl(src)} alt={city.name} className="h-56 w-full rounded-2xl object-cover shadow-sm" />
))}
</div>
);
@@ -573,7 +574,7 @@ function RelatedContent({ items, compact = false }: { items: Array<Record<string
const external = href.startsWith("http");
const body = (
<div className="flex gap-3 rounded-xl bg-gray-50 p-3 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700">
{!compact && <img src={String(item.coverImage || "")} alt="" className="h-14 w-20 rounded-lg object-cover" />}
{!compact && <img src={mediaUrl(String(item.coverImage || ""))} alt="" className="h-14 w-20 rounded-lg object-cover" />}
<div className="min-w-0">
<p className="line-clamp-1 text-sm font-semibold text-gray-900 dark:text-gray-100">{String(item.title)}</p>
<p className="mt-1 line-clamp-2 text-xs text-gray-500 dark:text-gray-400">{String(item.subtitle || "")}</p>

View File

@@ -2,6 +2,7 @@
import { ChangeEvent, FormEvent, useEffect, useMemo, useState } from "react";
import { apiFetch, apiUrl } from "@/app/lib/api-client";
import { mediaUrl } from "@/app/lib/media";
type SubmissionType = "ebook" | "video";
@@ -298,7 +299,7 @@ export default function ContentSubmissionModal({ open, locale, onClose, submissi
required
/>
{form.coverImage && (
<img src={form.coverImage} alt="" className="mt-3 h-32 w-full rounded-lg object-cover ring-1 ring-gray-100 dark:ring-gray-800" />
<img src={mediaUrl(form.coverImage)} alt="" className="mt-3 h-32 w-full rounded-lg object-cover ring-1 ring-gray-100 dark:ring-gray-800" />
)}
</div>

View File

@@ -11,6 +11,7 @@ import {
} from "@/app/lib/payment";
import type { PayChannel, PayEnv } from "@/app/lib/payment";
import { apiUrl } from "@/app/lib/api-client";
import { mediaUrl } from "@/app/lib/media";
const MEDIA_NAMES_ZH = ["36氪", "少数派", "极客公园", "虎嗅", "创业邦", "澎湃新闻"];
const MEDIA_NAMES_EN = ["36Kr", "sspai", "GeekPark", "Huxiu", "Cyzone", "The Paper"];
@@ -239,7 +240,7 @@ export default function HeroSection() {
{avatarPhotos.slice(0, 8).map((src, i) => (
<img
key={i}
src={src}
src={mediaUrl(src)}
alt=""
className="w-8 h-8 sm:w-9 sm:h-9 rounded-full border-2 border-white dark:border-gray-800 shadow-sm object-cover"
/>