S SmartDocs
系列: React.js javascript 234 行 · 更新於 2026-04-03

App.js

React.js/lessons/02_jsx/example/my-app/src/App.js

import logo from './logo.svg';
import './App.css';

function ProfileCard({ profile }) {
  const {
    name,
    title,
    company,
    email,
    phone,
    location,
    bio,
    skills,
    experience,
    isAvailable,
    socialLinks,
  } = profile;

  const cardStyle = {
    maxWidth: '420px',
    margin: '0 auto',
    borderRadius: '20px',
    overflow: 'hidden',
    boxShadow: '0 10px 40px rgba(0, 0, 0, 0.12)',
    fontFamily: "'Segoe UI', sans-serif",
    backgroundColor: '#fff',
  };

  const headerStyle = {
    background: 'linear-gradient(135deg, #0f172a 0%, #334155 100%)',
    padding: '40px 32px 60px',
    textAlign: 'center',
    position: 'relative',
  };

  const avatarStyle = {
    width: '90px',
    height: '90px',
    borderRadius: '50%',
    background: 'linear-gradient(135deg, #38bdf8 0%, #818cf8 100%)',
    color: 'white',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    fontSize: '2.2rem',
    fontWeight: 'bold',
    margin: '0 auto 16px',
    border: '4px solid rgba(255,255,255,0.2)',
  };

  const skillTagStyle = (index) => {
    const colors = ['#dbeafe', '#dcfce7', '#fef9c3', '#fce7f3', '#e0e7ff', '#f3e8ff'];
    const textColors = ['#1e40af', '#166534', '#854d0e', '#9d174d', '#3730a3', '#6b21a8'];
    return {
      display: 'inline-block',
      padding: '4px 12px',
      margin: '3px',
      borderRadius: '20px',
      backgroundColor: colors[index % colors.length],
      color: textColors[index % textColors.length],
      fontSize: '0.8rem',
      fontWeight: '600',
    };
  };

  const infoRowStyle = {
    display: 'flex',
    alignItems: 'center',
    gap: '10px',
    padding: '8px 0',
    color: '#475569',
    fontSize: '0.9rem',
  };

  return (
    <div style={cardStyle}>
      {/* 頭部 */}
      <div style={headerStyle}>
        <div style={avatarStyle}>{name.charAt(0)}</div>
        <h2 style={{ color: 'white', margin: '0 0 4px', fontSize: '1.5rem' }}>
          {name}
        </h2>
        <p style={{ color: '#94a3b8', margin: '0 0 4px' }}>{title}</p>
        <p style={{ color: '#64748b', margin: 0, fontSize: '0.85rem' }}>
          @ {company}
        </p>

        {/* 狀態標籤 */}
        {isAvailable && (
          <div
            style={{
              position: 'absolute',
              top: '16px',
              right: '16px',
              padding: '4px 12px',
              borderRadius: '20px',
              backgroundColor: 'rgba(74, 222, 128, 0.2)',
              color: '#4ade80',
              fontSize: '0.75rem',
              fontWeight: 'bold',
            }}
          >
            ● Open to Work
          </div>
        )}
      </div>

      {/* 內容 */}
      <div style={{ padding: '24px 32px' }}>
        {/* 簡介 */}
        {bio && (
          <p
            style={{
              color: '#64748b',
              lineHeight: 1.6,
              fontSize: '0.9rem',
              margin: '0 0 20px',
              borderLeft: '3px solid #818cf8',
              paddingLeft: '12px',
            }}
          >
            {bio}
          </p>
        )}

        {/* 資訊 */}
        <div style={{ marginBottom: '20px' }}>
          <div style={infoRowStyle}>
            <span>📧</span>
            <a href={`mailto:${email}`} style={{ color: '#6366f1', textDecoration: 'none' }}>
              {email}
            </a>
          </div>
          {phone && (
            <div style={infoRowStyle}>
              <span>📱</span>
              <span>{phone}</span>
            </div>
          )}
          <div style={infoRowStyle}>
            <span>📍</span>
            <span>{location}</span>
          </div>
          <div style={infoRowStyle}>
            <span>💼</span>
            <span>{experience} 年經驗</span>
          </div>
        </div>

        {/* 技能 */}
        <div style={{ marginBottom: '20px' }}>
          <h4 style={{ color: '#1e293b', margin: '0 0 8px', fontSize: '0.9rem' }}>
            技術能力
          </h4>
          <div>
            {skills.map((skill, index) => (
              <span key={index} style={skillTagStyle(index)}>
                {skill}
              </span>
            ))}
          </div>
        </div>

        {/* 社交連結 */}
        {socialLinks && socialLinks.length > 0 && (
          <div
            style={{
              display: 'flex',
              gap: '12px',
              justifyContent: 'center',
              paddingTop: '16px',
              borderTop: '1px solid #f1f5f9',
            }}
          >
            {socialLinks.map((link, index) => (
              <a
                key={index}
                href={link.url}
                style={{
                  padding: '8px 16px',
                  borderRadius: '8px',
                  backgroundColor: '#f1f5f9',
                  color: '#475569',
                  textDecoration: 'none',
                  fontSize: '0.85rem',
                  transition: 'all 0.2s',
                }}
              >
                {link.icon} {link.label}
              </a>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

function App() {
  const myProfile = {
    name: 'Alice Chen',
    title: '資深前端工程師',
    company: 'Tech Innovation Corp',
    email: 'alice.chen@techcorp.com',
    phone: '0912-345-678',
    location: 'Taipei, Taiwan',
    bio: '熱愛前端開發與使用者體驗設計,擅長 React 生態系與現代 Web 技術。喜歡分享技術知識與參與開源專案。',
    skills: ['React', 'TypeScript', 'Node.js', 'GraphQL', 'Tailwind CSS', 'Next.js'],
    experience: 5,
    isAvailable: true,
    socialLinks: [
      { icon: '🐙', label: 'GitHub', url: '#' },
      { icon: '💼', label: 'LinkedIn', url: '#' },
      { icon: '🐦', label: 'Twitter', url: '#' },
    ],
  };

  return (
    <div
      style={{
        minHeight: '100vh',
        backgroundColor: '#f1f5f9',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        padding: '20px',
      }}
    >
      <ProfileCard profile={myProfile} />
    </div>
  );
}

export default App;

相關文章