Design System 重构继续完成
This commit is contained in:
@@ -3,11 +3,11 @@
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Letter, SupportedAlphabets } from "@/lib/interfaces";
|
||||
import { IconClick, CircleToggleButton, CircleButton, PrimaryButton } from "@/components/ui/buttons";
|
||||
import { IconClick, CircleToggleButton, CircleButton, PrimaryButton } from "@/design-system/base/button";
|
||||
import { IMAGES } from "@/config/images";
|
||||
import { ChevronLeft, ChevronRight } from "lucide-react";
|
||||
import { PageLayout } from "@/components/ui/PageLayout";
|
||||
import { Card } from "@/components/ui/Card";
|
||||
import { Card } from "@/design-system/base/card";
|
||||
|
||||
interface AlphabetCardProps {
|
||||
alphabet: Letter[];
|
||||
@@ -103,7 +103,7 @@ export function AlphabetCard({ alphabet, alphabetType, onBack }: AlphabetCardPro
|
||||
{/* 右上角返回按钮 - outside the white card */}
|
||||
<div className="flex justify-end mb-4">
|
||||
<IconClick
|
||||
size={32}
|
||||
size="lg"
|
||||
alt="close"
|
||||
src={IMAGES.close}
|
||||
onClick={onBack}
|
||||
@@ -185,7 +185,7 @@ export function AlphabetCard({ alphabet, alphabetType, onBack }: AlphabetCardPro
|
||||
<div className="flex justify-between items-center">
|
||||
{/* 上一个按钮 */}
|
||||
<CircleButton onClick={goToPrevious} aria-label="上一个字母">
|
||||
<ChevronLeft size={24} />
|
||||
<ChevronLeft size={20} />
|
||||
</CircleButton>
|
||||
|
||||
{/* 中间区域:随机按钮 */}
|
||||
@@ -202,7 +202,7 @@ export function AlphabetCard({ alphabet, alphabetType, onBack }: AlphabetCardPro
|
||||
|
||||
{/* 下一个按钮 */}
|
||||
<CircleButton onClick={goToNext} aria-label="下一个字母">
|
||||
<ChevronRight size={24} />
|
||||
<ChevronRight size={20} />
|
||||
</CircleButton>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LightButton } from "@/components/ui/buttons";
|
||||
import { IconClick } from "@/components/ui/buttons";
|
||||
import { LightButton } from "@/design-system/base/button";
|
||||
import { IconClick } from "@/design-system/base/button";
|
||||
import { IMAGES } from "@/config/images";
|
||||
import { Letter, SupportedAlphabets } from "@/lib/interfaces";
|
||||
import {
|
||||
@@ -45,10 +45,10 @@ export function MemoryCard({
|
||||
className="w-full flex justify-center items-center"
|
||||
onKeyDown={(e: KeyboardEvent<HTMLDivElement>) => e.preventDefault()}
|
||||
>
|
||||
<div className="m-4 p-4 w-full md:w-[60dvw] flex-col rounded-2xl shadow border-gray-200 border flex justify-center items-center">
|
||||
<div className="m-4 p-4 w-full md:w-[60dvw] flex-col rounded-lg shadow border-gray-200 border flex justify-center items-center">
|
||||
<div className="w-full flex justify-end items-center">
|
||||
<IconClick
|
||||
size={32}
|
||||
size="lg"
|
||||
alt="close"
|
||||
src={IMAGES.close}
|
||||
onClick={() => setChosenAlphabet(null)}
|
||||
@@ -64,13 +64,13 @@ export function MemoryCard({
|
||||
</div>
|
||||
<div className="flex flex-row mt-32 items-center justify-center gap-2">
|
||||
<IconClick
|
||||
size={48}
|
||||
size="lg"
|
||||
alt="refresh"
|
||||
src={IMAGES.refresh}
|
||||
onClick={refresh}
|
||||
></IconClick>
|
||||
<IconClick
|
||||
size={48}
|
||||
size="lg"
|
||||
alt="more"
|
||||
src={IMAGES.more_horiz}
|
||||
onClick={() => setMore(!more)}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useState, useEffect } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Letter, SupportedAlphabets } from "@/lib/interfaces";
|
||||
import { PageLayout } from "@/components/ui/PageLayout";
|
||||
import { LightButton } from "@/components/ui/buttons";
|
||||
import { LightButton } from "@/design-system/base/button";
|
||||
import { AlphabetCard } from "./AlphabetCard";
|
||||
|
||||
export default function Alphabet() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { LightButton } from "@/components/ui/buttons";
|
||||
import { Input } from "@/components/ui/Input";
|
||||
import { LightButton } from "@/design-system/base/button";
|
||||
import { Input } from "@/design-system/base/input";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { Plus, RefreshCw } from "lucide-react";
|
||||
import { CircleButton, LightButton } from "@/components/ui/buttons";
|
||||
import { CircleButton, LightButton } from "@/design-system/base/button";
|
||||
import { toast } from "sonner";
|
||||
import { actionCreatePair } from "@/modules/folder/folder-aciton";
|
||||
import { TSharedItem } from "@/shared/dictionary-type";
|
||||
|
||||
@@ -6,7 +6,7 @@ import Link from "next/link";
|
||||
import { Folder as Fd } from "lucide-react";
|
||||
import { TSharedFolderWithTotalPairs } from "@/shared/folder-type";
|
||||
import { PageLayout } from "@/components/ui/PageLayout";
|
||||
import { PrimaryButton } from "@/components/ui/buttons";
|
||||
import { PrimaryButton } from "@/design-system/base/button";
|
||||
|
||||
interface FolderSelectorProps {
|
||||
folders: TSharedFolderWithTotalPairs[];
|
||||
@@ -37,7 +37,7 @@ const FolderSelector: React.FC<FolderSelectorProps> = ({ folders }) => {
|
||||
{t("selectFolder")}
|
||||
</h1>
|
||||
{/* 文件夹列表 */}
|
||||
<div className="border border-gray-200 rounded-2xl max-h-96 overflow-y-auto">
|
||||
<div className="border border-gray-200 rounded-lg max-h-96 overflow-y-auto">
|
||||
{folders
|
||||
.toSorted((a, b) => a.id - b.id)
|
||||
.map((folder) => (
|
||||
@@ -50,7 +50,7 @@ const FolderSelector: React.FC<FolderSelectorProps> = ({ folders }) => {
|
||||
>
|
||||
{/* 文件夹图标 */}
|
||||
<div className="shrink-0">
|
||||
<Fd className="text-gray-600" size={24} />
|
||||
<Fd className="text-gray-600" size="md" />
|
||||
</div>
|
||||
{/* 文件夹信息 */}
|
||||
<div className="flex-1">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { LinkButton, CircleToggleButton, LightButton } from "@/components/ui/buttons";
|
||||
import { LinkButton, CircleToggleButton, LightButton } from "@/design-system/base/button";
|
||||
import { useAudioPlayer } from "@/hooks/useAudioPlayer";
|
||||
import { getTTSUrl, TTS_SUPPORTED_LANGUAGES } from "@/lib/bigmodel/tts";
|
||||
import { useTranslations } from "next-intl";
|
||||
@@ -29,7 +29,7 @@ const Memorize: React.FC<MemorizeProps> = ({ textPairs }) => {
|
||||
|
||||
if (textPairs.length === 0) {
|
||||
return (
|
||||
<PageLayout maxWidth="md">
|
||||
<PageLayout>
|
||||
<p className="text-gray-700 text-center">{t("noTextPairs")}</p>
|
||||
</PageLayout>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState, useRef, forwardRef, useEffect, useCallback } from "react";
|
||||
import { SubtitleDisplay } from "./SubtitleDisplay";
|
||||
import { LightButton } from "@/components/ui/buttons";
|
||||
import { LightButton } from "@/design-system/base/button";
|
||||
import { RangeInput } from "@/components/ui/RangeInput";
|
||||
import { getIndex, parseSrt, getNearistIndex } from "../subtitle";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import React, { useRef } from "react";
|
||||
import { Button } from "@/components/ui/Button";
|
||||
import { Button } from "@/design-system/base/button";
|
||||
import { FileInputProps } from "../../types/controls";
|
||||
|
||||
interface FileInputComponentProps extends FileInputProps {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import React from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { LightButton } from "@/components/ui/buttons";
|
||||
import { LightButton } from "@/design-system/base/button";
|
||||
import { PlayButtonProps } from "../../types/player";
|
||||
|
||||
export function PlayButton({ isPlaying, onToggle, disabled, className }: PlayButtonProps) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { LightButton } from "@/components/ui/buttons";
|
||||
import { LightButton } from "@/design-system/base/button";
|
||||
import { SpeedControlProps } from "../../types/player";
|
||||
import { getPlaybackRateOptions, getPlaybackRateLabel } from "../../utils/timeUtils";
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import React from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { ChevronLeft, ChevronRight, RotateCcw, Pause } from "lucide-react";
|
||||
import { LightButton } from "@/components/ui/buttons";
|
||||
import { LightButton } from "@/design-system/base/button";
|
||||
import { ControlBarProps } from "../../types/controls";
|
||||
import { PlayButton } from "../atoms/PlayButton";
|
||||
import { SpeedControl } from "../atoms/SpeedControl";
|
||||
|
||||
@@ -4,7 +4,7 @@ import React from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { toast } from "sonner";
|
||||
import { Video, FileText } from "lucide-react";
|
||||
import { LightButton } from "@/components/ui/buttons";
|
||||
import { LightButton } from "@/design-system/base/button";
|
||||
import { FileUploadProps } from "../../types/controls";
|
||||
import { useFileUpload } from "../../hooks/useFileUpload";
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import { SubtitleArea } from "./components/compounds/SubtitleArea";
|
||||
import { ControlBar } from "./components/compounds/ControlBar";
|
||||
import { UploadZone } from "./components/compounds/UploadZone";
|
||||
import { SeekBar } from "./components/atoms/SeekBar";
|
||||
import { LightButton } from "@/components/ui/buttons";
|
||||
import { LightButton } from "@/design-system/base/button";
|
||||
|
||||
export default function SrtPlayerPage() {
|
||||
const t = useTranslations("home");
|
||||
@@ -119,7 +119,7 @@ export default function SrtPlayerPage() {
|
||||
</div>
|
||||
|
||||
{/* 视频播放器区域 */}
|
||||
<div className="aspect-video bg-black relative rounded-xl overflow-hidden">
|
||||
<div className="aspect-video bg-black relative rounded-md overflow-hidden">
|
||||
{(!state.video.url || !state.subtitle.url || state.subtitle.data.length === 0) && (
|
||||
<div className="absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-75 z-10">
|
||||
<div className="text-center text-white">
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
TextSpeakerArraySchema,
|
||||
TextSpeakerItemSchema,
|
||||
} from "@/lib/interfaces";
|
||||
import { IconClick } from "@/components/ui/buttons";
|
||||
import { IconClick } from "@/design-system/base/button";
|
||||
import { IMAGES } from "@/config/images";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getLocalStorageOperator } from "@/lib/browser/localStorageOperators";
|
||||
@@ -24,7 +24,7 @@ function TextCard({ item, handleUse, handleDel }: TextCardProps) {
|
||||
handleDel(item);
|
||||
};
|
||||
return (
|
||||
<div className="p-2 border-b border-gray-200 rounded-2xl bg-gray-100 m-2 grid grid-cols-8">
|
||||
<div className="p-2 border-b border-gray-200 rounded-lg bg-gray-100 m-2 grid grid-cols-8">
|
||||
<div className="col-span-7" onClick={onUseClick}>
|
||||
<div className="max-h-26 hover:cursor-pointer text-3xl overflow-y-auto">
|
||||
{item.text}
|
||||
@@ -39,7 +39,7 @@ function TextCard({ item, handleUse, handleDel }: TextCardProps) {
|
||||
alt="delete"
|
||||
onClick={onDelClick}
|
||||
className="place-self-center"
|
||||
size={42}
|
||||
size="lg"
|
||||
></IconClick>
|
||||
</div>
|
||||
</div>
|
||||
@@ -81,7 +81,7 @@ export function SaveList({ show = false, handleUse }: SaveListProps) {
|
||||
if (show)
|
||||
return (
|
||||
<div
|
||||
className="my-4 p-2 mx-4 md:mx-32 border border-gray-200 rounded-2xl"
|
||||
className="my-4 p-2 mx-4 md:mx-32 border border-gray-200 rounded-lg"
|
||||
style={{ fontFamily: "Times New Roman, serif" }}
|
||||
>
|
||||
<div className="flex flex-row justify-center gap-8 items-center">
|
||||
@@ -89,14 +89,14 @@ export function SaveList({ show = false, handleUse }: SaveListProps) {
|
||||
src={IMAGES.refresh}
|
||||
alt="refresh"
|
||||
onClick={refresh}
|
||||
size={48}
|
||||
size="lg"
|
||||
className=""
|
||||
></IconClick>
|
||||
<IconClick
|
||||
src={IMAGES.delete}
|
||||
alt="delete"
|
||||
onClick={handleDeleteAll}
|
||||
size={48}
|
||||
size="lg"
|
||||
className=""
|
||||
></IconClick>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { LightButton } from "@/components/ui/buttons";
|
||||
import { IconClick } from "@/components/ui/buttons";
|
||||
import { LightButton } from "@/design-system/base/button";
|
||||
import { IconClick } from "@/design-system/base/button";
|
||||
import { IMAGES } from "@/config/images";
|
||||
import { useAudioPlayer } from "@/hooks/useAudioPlayer";
|
||||
import {
|
||||
@@ -222,7 +222,7 @@ export default function TextSpeakerPage() {
|
||||
<PageLayout className="items-start py-4">
|
||||
{/* 文本输入区域 */}
|
||||
<div
|
||||
className="border border-gray-200 rounded-2xl"
|
||||
className="border border-gray-200 rounded-lg"
|
||||
style={{ fontFamily: "Times New Roman, serif" }}
|
||||
>
|
||||
{/* 文本输入框 */}
|
||||
@@ -242,37 +242,37 @@ export default function TextSpeakerPage() {
|
||||
<div className="p-4 relative w-full flex flex-row flex-wrap gap-2 justify-center items-center">
|
||||
{/* 速度调节面板 */}
|
||||
{showSpeedAdjust && (
|
||||
<div className="bg-white p-6 rounded-2xl border-gray-200 border-2 shadow-2xl absolute left-1/2 -translate-x-1/2 -translate-y-full -top-4 flex flex-row flex-wrap gap-2 justify-center items-center z-10">
|
||||
<div className="bg-white p-6 rounded-lg border-gray-200 border-2 shadow-2xl absolute left-1/2 -translate-x-1/2 -translate-y-full -top-4 flex flex-row flex-wrap gap-2 justify-center items-center z-10">
|
||||
<IconClick
|
||||
size={45}
|
||||
size="lg"
|
||||
onClick={letMeSetSpeed(0.5)}
|
||||
src={IMAGES.speed_0_5x}
|
||||
alt="0.5x"
|
||||
className={speed === 0.5 ? "bg-gray-200" : ""}
|
||||
></IconClick>
|
||||
<IconClick
|
||||
size={45}
|
||||
size="lg"
|
||||
onClick={letMeSetSpeed(0.7)}
|
||||
src={IMAGES.speed_0_7x}
|
||||
alt="0.7x"
|
||||
className={speed === 0.7 ? "bg-gray-200" : ""}
|
||||
></IconClick>
|
||||
<IconClick
|
||||
size={45}
|
||||
size="lg"
|
||||
onClick={letMeSetSpeed(1)}
|
||||
src={IMAGES.speed_1x}
|
||||
alt="1x"
|
||||
className={speed === 1 ? "bg-gray-200" : ""}
|
||||
></IconClick>
|
||||
<IconClick
|
||||
size={45}
|
||||
size="lg"
|
||||
onClick={letMeSetSpeed(1.2)}
|
||||
src={IMAGES.speed_1_2_x}
|
||||
alt="1.2x"
|
||||
className={speed === 1.2 ? "bg-gray-200" : ""}
|
||||
></IconClick>
|
||||
<IconClick
|
||||
size={45}
|
||||
size="lg"
|
||||
onClick={letMeSetSpeed(1.5)}
|
||||
src={IMAGES.speed_1_5x}
|
||||
alt="1.5x"
|
||||
@@ -282,7 +282,7 @@ export default function TextSpeakerPage() {
|
||||
)}
|
||||
{/* 播放/暂停按钮 */}
|
||||
<IconClick
|
||||
size={45}
|
||||
size="lg"
|
||||
onClick={speak}
|
||||
src={pause ? IMAGES.play_arrow : IMAGES.pause}
|
||||
alt="playorpause"
|
||||
@@ -290,7 +290,7 @@ export default function TextSpeakerPage() {
|
||||
></IconClick>
|
||||
{/* 自动暂停按钮 */}
|
||||
<IconClick
|
||||
size={45}
|
||||
size="lg"
|
||||
onClick={() => {
|
||||
setAutopause(!autopause);
|
||||
if (objurlRef) {
|
||||
@@ -303,7 +303,7 @@ export default function TextSpeakerPage() {
|
||||
></IconClick>
|
||||
{/* 速度调节按钮 */}
|
||||
<IconClick
|
||||
size={45}
|
||||
size="lg"
|
||||
onClick={() => setShowSpeedAdjust(!showSpeedAdjust)}
|
||||
src={IMAGES.speed}
|
||||
alt="speed"
|
||||
@@ -311,7 +311,7 @@ export default function TextSpeakerPage() {
|
||||
></IconClick>
|
||||
{/* 保存按钮 */}
|
||||
<IconClick
|
||||
size={45}
|
||||
size="lg"
|
||||
onClick={save}
|
||||
src={IMAGES.save}
|
||||
alt="save"
|
||||
@@ -338,7 +338,7 @@ export default function TextSpeakerPage() {
|
||||
</div>
|
||||
{/* 保存列表 */}
|
||||
{showSaveList && (
|
||||
<div className="mt-4 border border-gray-200 rounded-2xl overflow-hidden">
|
||||
<div className="mt-4 border border-gray-200 rounded-lg overflow-hidden">
|
||||
<SaveList show={showSaveList} handleUse={handleUseItem}></SaveList>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { LightButton, PrimaryButton } from "@/components/ui/buttons";
|
||||
import { IconClick } from "@/components/ui/buttons";
|
||||
import { LightButton, PrimaryButton, IconClick } from "@/design-system/base/button";
|
||||
import { IMAGES } from "@/config/images";
|
||||
import { useAudioPlayer } from "@/hooks/useAudioPlayer";
|
||||
import { useTranslations } from "next-intl";
|
||||
@@ -101,7 +100,7 @@ export default function TranslatorPage() {
|
||||
{/* Card Component - Left Side */}
|
||||
<div className="w-full md:w-1/2 flex flex-col-reverse gap-2">
|
||||
{/* ICard1 Component */}
|
||||
<div className="border border-gray-200 rounded-2xl w-full h-64 p-2">
|
||||
<div className="border border-gray-200 rounded-lg w-full h-64 p-2">
|
||||
<textarea
|
||||
className="resize-none h-8/12 w-full focus:outline-0"
|
||||
ref={taref}
|
||||
@@ -147,7 +146,7 @@ export default function TranslatorPage() {
|
||||
{/* Card Component - Right Side */}
|
||||
<div className="w-full md:w-1/2 flex flex-col-reverse gap-2">
|
||||
{/* ICard2 Component */}
|
||||
<div className="bg-gray-100 rounded-2xl w-full h-64 p-2">
|
||||
<div className="bg-gray-100 rounded-lg w-full h-64 p-2">
|
||||
<div className="h-2/3 w-full overflow-y-auto">{translationResult?.translatedText || ""}</div>
|
||||
<div className="ipa w-full h-1/6 overflow-y-auto text-gray-600">
|
||||
{translationResult?.targetIpa || ""}
|
||||
@@ -213,7 +212,8 @@ export default function TranslatorPage() {
|
||||
<PrimaryButton
|
||||
onClick={translate}
|
||||
disabled={processing}
|
||||
className="text-xl h-16 px-8"
|
||||
size="lg"
|
||||
className="text-xl"
|
||||
>
|
||||
{t("translate")}
|
||||
</PrimaryButton>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
import { useState, useActionState, startTransition } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { PageLayout } from "@/components/ui/PageLayout";
|
||||
import { Input } from "@/components/ui/Input";
|
||||
import { LightButton, LinkButton } from "@/components/ui/buttons";
|
||||
import { Input } from "@/design-system/base/input";
|
||||
import { LightButton, LinkButton } from "@/design-system/base/button";
|
||||
import { authClient } from "@/lib/auth-client";
|
||||
import { actionSignIn, actionSignUp, ActionOutputAuth } from "@/modules/auth/auth-action";
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
FolderPlus,
|
||||
Trash2,
|
||||
} from "lucide-react";
|
||||
import { CircleButton, DashedButton } from "@/components/ui/buttons";
|
||||
import { CircleButton, DashedButton } from "@/design-system/base/button";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useTranslations } from "next-intl";
|
||||
@@ -36,7 +36,7 @@ const FolderCard = ({ folder, refresh }: FolderProps) => {
|
||||
>
|
||||
<div className="flex items-center gap-3 flex-1">
|
||||
<div className="shrink-0">
|
||||
<Fd className="text-gray-600" size={24} />
|
||||
<Fd className="text-gray-600" size="md" />
|
||||
</div>
|
||||
|
||||
<div className="flex-1">
|
||||
@@ -167,13 +167,13 @@ export function FoldersClient({ userId }: { userId: string; }) {
|
||||
// 空状态
|
||||
<div className="text-center py-12 text-gray-400">
|
||||
<div className="w-16 h-16 mx-auto mb-3 rounded-full bg-gray-100 flex items-center justify-center">
|
||||
<FolderPlus size={24} className="text-gray-400" />
|
||||
<FolderPlus size="md" className="text-gray-400" />
|
||||
</div>
|
||||
<p className="text-sm">{t("noFoldersYet")}</p>
|
||||
</div>
|
||||
) : (
|
||||
// 文件夹卡片列表
|
||||
<div className="rounded-xl border border-gray-200 overflow-hidden">
|
||||
<div className="rounded-md border border-gray-200 overflow-hidden">
|
||||
{folders
|
||||
.toSorted((a, b) => a.id - b.id)
|
||||
.map((folder) => (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LightButton } from "@/components/ui/buttons";
|
||||
import { Input } from "@/components/ui/Input";
|
||||
import { LightButton } from "@/design-system/base/button";
|
||||
import { Input } from "@/design-system/base/input";
|
||||
import { LocaleSelector } from "@/components/ui/LocaleSelector";
|
||||
import { X } from "lucide-react";
|
||||
import { useRef, useState } from "react";
|
||||
@@ -67,7 +67,7 @@ export function AddTextPairModal({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="bg-white rounded-xl p-6 w-full max-w-md mx-4">
|
||||
<div className="bg-white rounded-md p-6 w-full max-w-md mx-4">
|
||||
<div className="flex">
|
||||
<h2 className="flex-1 text-xl font-light mb-4 text-center">
|
||||
{t("addNewTextPair")}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { AddTextPairModal } from "./AddTextPairModal";
|
||||
import { TextPairCard } from "./TextPairCard";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { PageLayout } from "@/components/ui/PageLayout";
|
||||
import { PrimaryButton, IconButton, LinkButton } from "@/components/ui/buttons";
|
||||
import { PrimaryButton, IconButton, LinkButton } from "@/design-system/base/button";
|
||||
import { CardList } from "@/components/ui/CardList";
|
||||
import { actionCreatePair, actionDeletePairById, actionGetPairsByFolderId } from "@/modules/folder/folder-aciton";
|
||||
import { TSharedPair } from "@/shared/folder-type";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Edit, Trash2 } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { CircleButton } from "@/components/ui/buttons";
|
||||
import { CircleButton } from "@/design-system/base/button";
|
||||
import { UpdateTextPairModal } from "./UpdateTextPairModal";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { TSharedPair } from "@/shared/folder-type";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LightButton } from "@/components/ui/buttons";
|
||||
import { Input } from "@/components/ui/Input";
|
||||
import { LightButton } from "@/design-system/base/button";
|
||||
import { Input } from "@/design-system/base/input";
|
||||
import { LocaleSelector } from "@/components/ui/LocaleSelector";
|
||||
import { X } from "lucide-react";
|
||||
import { useRef, useState } from "react";
|
||||
@@ -63,7 +63,7 @@ export function UpdateTextPairModal({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="bg-white rounded-xl p-6 w-full max-w-md mx-4">
|
||||
<div className="bg-white rounded-md p-6 w-full max-w-md mx-4">
|
||||
<div className="flex">
|
||||
<h2 className="flex-1 text-xl font-light mb-4 text-center">
|
||||
{t("updateTextPair")}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
/**
|
||||
* Design System CSS 变量
|
||||
*
|
||||
* 定义全局 CSS 变量用于主题切换和动态样式
|
||||
* Tailwind CSS v4 主题配置
|
||||
* 使用 @theme 指令定义主题变量
|
||||
*/
|
||||
:root {
|
||||
/* 颜色系统 */
|
||||
@theme {
|
||||
/* 主色 - Teal */
|
||||
--color-primary-50: #f0f9f8;
|
||||
--color-primary-100: #e0f2f0;
|
||||
--color-primary-200: #bce6e1;
|
||||
@@ -19,12 +18,88 @@
|
||||
--color-primary-900: #122826;
|
||||
--color-primary-950: #0a1413;
|
||||
|
||||
/* 语义色 */
|
||||
--color-success-500: #22c55e;
|
||||
--color-warning-500: #f59e0b;
|
||||
--color-error-500: #ef4444;
|
||||
--color-info-500: #3b82f6;
|
||||
/* 中性色 */
|
||||
--color-gray-50: #f9fafb;
|
||||
--color-gray-100: #f3f4f6;
|
||||
--color-gray-200: #e5e7eb;
|
||||
--color-gray-300: #d1d5db;
|
||||
--color-gray-400: #9ca3af;
|
||||
--color-gray-500: #6b7280;
|
||||
--color-gray-600: #4b5563;
|
||||
--color-gray-700: #374151;
|
||||
--color-gray-800: #1f2937;
|
||||
--color-gray-900: #111827;
|
||||
--color-gray-950: #030712;
|
||||
|
||||
/* 语义色 - Success */
|
||||
--color-success-50: #f0fdf4;
|
||||
--color-success-100: #dcfce7;
|
||||
--color-success-200: #bbf7d0;
|
||||
--color-success-300: #86efac;
|
||||
--color-success-400: #4ade80;
|
||||
--color-success-500: #22c55e;
|
||||
--color-success-600: #16a34a;
|
||||
--color-success-700: #15803d;
|
||||
--color-success-800: #166534;
|
||||
--color-success-900: #14532d;
|
||||
--color-success-950: #052e16;
|
||||
|
||||
/* 语义色 - Warning */
|
||||
--color-warning-50: #fffbeb;
|
||||
--color-warning-100: #fef3c7;
|
||||
--color-warning-200: #fde68a;
|
||||
--color-warning-300: #fcd34d;
|
||||
--color-warning-400: #fbbf24;
|
||||
--color-warning-500: #f59e0b;
|
||||
--color-warning-600: #d97706;
|
||||
--color-warning-700: #b45309;
|
||||
--color-warning-800: #92400e;
|
||||
--color-warning-900: #78350f;
|
||||
--color-warning-950: #451a03;
|
||||
|
||||
/* 语义色 - Error */
|
||||
--color-error-50: #fef2f2;
|
||||
--color-error-100: #fee2e2;
|
||||
--color-error-200: #fecaca;
|
||||
--color-error-300: #fca5a5;
|
||||
--color-error-400: #f87171;
|
||||
--color-error-500: #ef4444;
|
||||
--color-error-600: #dc2626;
|
||||
--color-error-700: #b91c1c;
|
||||
--color-error-800: #991b1b;
|
||||
--color-error-900: #7f1d1d;
|
||||
--color-error-950: #450a0a;
|
||||
|
||||
/* 语义色 - Info */
|
||||
--color-info-50: #eff6ff;
|
||||
--color-info-100: #dbeafe;
|
||||
--color-info-200: #bfdbfe;
|
||||
--color-info-300: #93c5fd;
|
||||
--color-info-400: #60a5fa;
|
||||
--color-info-500: #3b82f6;
|
||||
--color-info-600: #2563eb;
|
||||
--color-info-700: #1d4ed8;
|
||||
--color-info-800: #1e40af;
|
||||
--color-info-900: #1e3a8a;
|
||||
--color-info-950: #172554;
|
||||
|
||||
/* 圆角 - 更小的圆角 */
|
||||
--radius-xs: 0.125rem;
|
||||
--radius-sm: 0.25rem;
|
||||
--radius-md: 0.375rem;
|
||||
--radius-lg: 0.5rem;
|
||||
--radius-xl: 0.625rem;
|
||||
--radius-2xl: 0.75rem;
|
||||
--radius-3xl: 1rem;
|
||||
--radius-full: 9999px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Design System CSS 变量
|
||||
*
|
||||
* 定义全局 CSS 变量用于主题切换和动态样式
|
||||
*/
|
||||
:root {
|
||||
/* 基础颜色 */
|
||||
--background: #ffffff;
|
||||
--foreground: #111827;
|
||||
@@ -41,13 +116,14 @@
|
||||
--border-secondary: #e5e7eb;
|
||||
--border-focus: #35786f;
|
||||
|
||||
/* 圆角 */
|
||||
--radius-sm: 0.125rem;
|
||||
/* 圆角 - 更小的圆角 */
|
||||
--radius-xs: 0.125rem;
|
||||
--radius-sm: 0.25rem;
|
||||
--radius-md: 0.375rem;
|
||||
--radius-lg: 0.5rem;
|
||||
--radius-xl: 0.75rem;
|
||||
--radius-2xl: 1rem;
|
||||
--radius-3xl: 1.5rem;
|
||||
--radius-xl: 0.625rem;
|
||||
--radius-2xl: 0.75rem;
|
||||
--radius-3xl: 1rem;
|
||||
--radius-full: 9999px;
|
||||
|
||||
/* 阴影 */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { LightButton } from "@/components/ui/buttons";
|
||||
import { LightButton } from "@/design-system/base/button";
|
||||
import { authClient } from "@/lib/auth-client";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { PageLayout } from "@/components/ui/PageLayout";
|
||||
import { LinkButton } from "@/components/ui/buttons";
|
||||
import { LinkButton } from "@/design-system/base/button";
|
||||
import { actionGetUserProfileByUsername } from "@/modules/auth/auth-action";
|
||||
import { repoGetFoldersWithTotalPairsByUserId } from "@/modules/folder/folder-repository";
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
Reference in New Issue
Block a user