Home.jsx 2.66 KB
Newer Older
fisherdaddy's avatar
fisherdaddy committed
1 2 3
import React from 'react';
import { Link } from 'react-router-dom';
import { useTranslation } from '../js/i18n';
fisherdaddy's avatar
fisherdaddy committed
4
import SEO from '../components/SEO';
fisherdaddy's avatar
fisherdaddy committed
5 6

const tools = [
fisherdaddy's avatar
fisherdaddy committed
7
  { id: 'handwrite', icon: '/assets/icon/handwrite.png', path: '/handwriting' },
8
  { id: 'quoteCard', icon: '/assets/icon/quotecard.png', path: '/quote-card' },
9
  { id: 'markdown2image', icon: '/assets/icon/markdown2image.png', path: '/markdown-to-image' },
10
  { id: 'subtitleGenerator', icon: '/assets/icon/subtitle2image.png', path: '/subtitle-to-image' },
11
  { id: 'imageCompressor', icon: '/assets/icon/image-compressor.png', path: '/image-compressor' },
fisherdaddy's avatar
fisherdaddy committed
12
  
13
  { id: 'latex2image', icon: '/assets/icon/latex2image.png', path: '/latex-to-image' },
fisherdaddy's avatar
fisherdaddy committed
14 15 16
  { id: 'jsonFormatter', icon: '/assets/icon/json-format.png', path: '/json-formatter' },
  { id: 'urlEncodeDecode', icon: '/assets/icon/url-endecode.png', path: '/url-encode-and-decode' },
  { id: 'imageBase64Converter', icon: '/assets/icon/image-base64.png', path: '/image-base64' },
fisherdaddy's avatar
fisherdaddy committed
17 18
  { id: 'textDiff', icon: '/assets/icon/diff.png', path: '/text-diff' },

fisherdaddy's avatar
fisherdaddy committed
19 20 21
  { id: 'openAITimeline', icon: '/assets/icon/openai_small.svg', path: '/openai-timeline' },
  { id: 'modelPrice', icon: '/assets/icon/openai_small.svg', path: '/llm-model-price' },
  { id: 'fisherai', icon: '/assets/icon/fisherai.png', path: 'https://chromewebstore.google.com/detail/fisherai-your-best-summar/ipfiijaobcenaibdpaacbbpbjefgekbj', external: true } // 新增外部链接
fisherdaddy's avatar
fisherdaddy committed
22 23
];

fisherdaddy's avatar
fisherdaddy committed
24
const Home = () => {
fisherdaddy's avatar
fisherdaddy committed
25
  const { t } = useTranslation();
fisherdaddy's avatar
fisherdaddy committed
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
  const renderToolLink = (tool) => {
    const content = (
      <>
        <img 
          src={tool.icon} 
          alt={`${t(`tools.${tool.id}.title`)} icon`} 
          className="tool-icon" 
          loading="lazy" 
        />
        <div className="tool-content">
          <h3 className="tool-title">{t(`tools.${tool.id}.title`)}</h3>
          <p className="tool-description">{t(`tools.${tool.id}.description`)}</p>
        </div>
      </>
    );

    return tool.external ? (
      <a 
        href={tool.path}
        className="tool-card"
        target="_blank"
        rel="noopener noreferrer"
      >
        {content}
      </a>
    ) : (
      <Link to={tool.path} className="tool-card">
        {content}
      </Link>
    );
  };

fisherdaddy's avatar
fisherdaddy committed
59
  return (
fisherdaddy's avatar
fisherdaddy committed
60 61 62 63 64 65 66 67 68
    <>
      <SEO
        title={t('title')}
        description={t('slogan')}
      />
      <main>
        <section className="tools-section">
          <div className="tools-grid">
            {tools.map(tool => (
69 70 71
              <React.Fragment key={tool.id}>
                {renderToolLink(tool)}
              </React.Fragment>
fisherdaddy's avatar
fisherdaddy committed
72 73 74 75 76
            ))}
          </div>
        </section>
      </main>
    </>
fisherdaddy's avatar
fisherdaddy committed
77
  );
fisherdaddy's avatar
fisherdaddy committed
78
};
fisherdaddy's avatar
fisherdaddy committed
79 80

export default Home;