Skip to content

Commit 7fef9bd

Browse files
committed
ui(web): Show nationality, representative company, and short intro
1 parent 78bfdda commit 7fef9bd

5 files changed

Lines changed: 112 additions & 4 deletions

File tree

config/investor_index.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ investors:
1616
- id: warren_buffett
1717
full_name: Warren Buffett
1818
chinese_name: 沃伦·巴菲特
19+
nationality: 美国
20+
intro_zh: 价值投资与“护城河”理念的代表,强调在合理价格买入优质企业并长期持有,以资本配置创造复利。
1921
fund: Berkshire Hathaway
2022
aum: "$900B+"
2123
active_years: "1965-present"
@@ -59,6 +61,8 @@ investors:
5961
- id: charlie_munger
6062
full_name: Charlie Munger
6163
chinese_name: 查理·芒格
64+
nationality: 美国
65+
intro_zh: “多学科思维模型”倡导者,强调避免愚蠢、逆向思考与高质量决策,在长期复利中追求少而精的下注。
6266
fund: Berkshire Hathaway / Daily Journal
6367
aum: "N/A (Partner)"
6468
active_years: "1978-2023"
@@ -99,6 +103,8 @@ investors:
99103
- id: peter_lynch
100104
full_name: Peter Lynch
101105
chinese_name: 彼得·林奇
106+
nationality: 美国
107+
intro_zh: GARP(合理价格成长)代表人物,强调自下而上选股与“你身边就有机会”,用分类与 PEG 框架捕捉成长股。
102108
fund: Fidelity Magellan Fund
103109
aum: "Peak $14B (1990)"
104110
active_years: "1977-1990"
@@ -134,6 +140,8 @@ investors:
134140
- id: seth_klarman
135141
full_name: Seth Klarman
136142
chinese_name: 塞斯·卡拉曼
143+
nationality: 美国
144+
intro_zh: 深度价值与困境投资代表,强调安全边际、绝对回报与耐心,在市场恐慌中寻找被迫抛售带来的机会。
137145
fund: Baupost Group
138146
aum: "$27B"
139147
active_years: "1982-present"
@@ -174,6 +182,8 @@ investors:
174182
- id: ray_dalio
175183
full_name: Ray Dalio
176184
chinese_name: 雷·达利奥
185+
nationality: 美国
186+
intro_zh: 宏观与系统化交易代表,提出“经济机器/债务周期”框架与全天候配置,强调规则化与风险平价思维。
177187
fund: Bridgewater Associates
178188
aum: "$120B"
179189
active_years: "1975-present"
@@ -211,6 +221,8 @@ investors:
211221
- id: stanley_druckenmiller
212222
full_name: Stanley Druckenmiller
213223
chinese_name: 斯坦利·德鲁肯米勒
224+
nationality: 美国
225+
intro_zh: 宏观择时与流动性派代表,强调顺势、集中下注与仓位/确信度管理,紧盯政策与流动性拐点。
214226
fund: Duquesne Capital (Closed) / Quantum Fund
215227
aum: "Peak $12B"
216228
active_years: "1981-2010 (fund), present (family office)"
@@ -248,6 +260,8 @@ investors:
248260
- id: george_soros
249261
full_name: George Soros
250262
chinese_name: 乔治·索罗斯
263+
nationality: 美国(匈牙利裔)
264+
intro_zh: 宏观交易与反身性理论代表,擅长在政策与预期错配中捕捉趋势变化,强调“先活下来”的风控纪律。
251265
fund: Quantum Fund
252266
aum: "Peak $25B"
253267
active_years: "1973-2011"
@@ -286,6 +300,8 @@ investors:
286300
- id: howard_marks
287301
full_name: Howard Marks
288302
chinese_name: 霍华德·马克斯
303+
nationality: 美国
304+
intro_zh: 信用周期与逆向思考代表,强调第二层思考、风险控制与周期位置判断,在极端情绪下追求非对称回报。
289305
fund: Oaktree Capital
290306
aum: "$190B"
291307
active_years: "1995-present"
@@ -323,6 +339,8 @@ investors:
323339
- id: michael_burry
324340
full_name: Michael Burry
325341
chinese_name: 迈克尔·伯里
342+
nationality: 美国
343+
intro_zh: 深度价值与极端逆向代表,重视独立研究与估值偏离,擅长在泡沫与信用过热时寻找做空/对冲机会。
326344
fund: Scion Asset Management
327345
aum: "~$250M"
328346
active_years: "2000-2008, 2013-present"
@@ -361,6 +379,8 @@ investors:
361379
- id: carl_icahn
362380
full_name: Carl Icahn
363381
chinese_name: 卡尔·伊坎
382+
nationality: 美国
383+
intro_zh: 激进投资与事件驱动代表,通过公司治理与资本运作释放价值,擅长在公司行动中寻找收益空间。
364384
fund: Icahn Enterprises
365385
aum: "$15B+"
366386
active_years: "1968-present"
@@ -397,6 +417,8 @@ investors:
397417
- id: james_simons
398418
full_name: James Simons
399419
chinese_name: 詹姆斯·西蒙斯
420+
nationality: 美国
421+
intro_zh: 量化对冲基金先驱,强调数据驱动与模型迭代,以系统化方法在长期统计优势中获取收益。
400422
fund: Renaissance Technologies
401423
aum: "$130B"
402424
active_years: "1982-2010 (active), 2010-present (emeritus)"
@@ -432,6 +454,8 @@ investors:
432454
- id: ed_thorp
433455
full_name: Ed Thorp
434456
chinese_name: 爱德华·索普
457+
nationality: 美国
458+
intro_zh: 量化与套利先驱,提出凯利公式并将数学优势用于期权定价与统计套利,强调风险优先与纪律化执行。
435459
fund: Princeton Newport Partners
436460
aum: "Peak ~$270M (1988)"
437461
active_years: "1969-1988"
@@ -467,6 +491,8 @@ investors:
467491
- id: cliff_asness
468492
full_name: Cliff Asness
469493
chinese_name: 克利夫·阿斯内斯
494+
nationality: 美国
495+
intro_zh: 因子投资与系统化组合构建代表,聚焦价值/动量等风险溢价的长期捕捉,并重视分散与稳健执行。
470496
fund: AQR Capital Management
471497
aum: "$100B+"
472498
active_years: "1998-present"
@@ -503,6 +529,8 @@ investors:
503529
- id: qiu_guolu
504530
full_name: Qiu Guolu
505531
chinese_name: 邱国鹭
532+
nationality: 中国
533+
intro_zh: 中国价值投资代表,强调行业选择与“护城河”验证,用估值锚与逆向思维在 A 股寻找高确定性机会。
506534
fund: 高毅资产
507535
aum: "~$15B (高毅)"
508536
active_years: "2000-present"
@@ -542,6 +570,8 @@ investors:
542570
- id: feng_liu
543571
full_name: Feng Liu
544572
chinese_name: 冯柳
573+
nationality: 中国
574+
intro_zh: 逆向与左侧交易代表,强调“赔率优先”,在信息不完美的情况下做高胜率/高赔率的结构化决策。
545575
fund: 高毅资产
546576
aum: "~$8B (个人管理)"
547577
active_years: "2003-present"
@@ -581,6 +611,8 @@ investors:
581611
- id: duan_yongping
582612
full_name: Duan Yongping
583613
chinese_name: 段永平
614+
nationality: 中国
615+
intro_zh: 价值投资与商业模式派代表,强调“买股票就是买公司”“不懂不做”,偏好少而精、长期持有的好公司。
584616
fund: 个人投资者 / 步步高系创始人
585617
aum: "N/A (个人)"
586618
active_years: "2001-present"
@@ -619,6 +651,8 @@ investors:
619651
- id: greg_abel
620652
full_name: Greg Abel
621653
chinese_name: 格雷格·阿贝尔
654+
nationality: 加拿大
655+
intro_zh: 实业经营与长期资本配置代表,聚焦公用事业/受监管行业的稳健回报,以运营效率与长周期资产管理见长。
622656
fund: Berkshire Hathaway Energy
623657
aum: "$140B+ (BHE assets)"
624658
active_years: "2000-present"

web/src/components/InvestorDetail.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,17 @@ export default function InvestorDetail({
8080
<Typography color="text.primary">{investor.chinese_name}</Typography>
8181
</Breadcrumbs>
8282

83-
<Paper sx={{ p: 4, mb: 4, bgcolor: 'primary.main', color: 'primary.contrastText' }}>
83+
<Paper
84+
sx={{
85+
p: 4,
86+
mb: 4,
87+
color: 'primary.contrastText',
88+
background:
89+
'radial-gradient(1200px circle at 10% 10%, rgba(255,255,255,0.18), rgba(255,255,255,0) 55%), linear-gradient(135deg, #1a73e8 0%, #2563eb 35%, #0ea5e9 100%)',
90+
borderRadius: 3,
91+
border: '1px solid rgba(255,255,255,0.2)',
92+
}}
93+
>
8494
<Stack direction="row" spacing={2} alignItems="center" sx={{ mb: 1 }}>
8595
<Avatar
8696
src={!missingAvatar ? getAvatarUrl(investor) ?? undefined : undefined}
@@ -102,8 +112,18 @@ export default function InvestorDetail({
102112
<Typography variant="h6" sx={{ opacity: 0.9 }}>
103113
{investor.full_name}
104114
</Typography>
115+
<Typography variant="body2" sx={{ opacity: 0.92, mt: 0.5 }}>
116+
{(investor.nationality || '—')}{investor.fund ? ` · ${investor.fund}` : ''}
117+
</Typography>
105118
</Box>
106119
</Stack>
120+
121+
{(investor.intro_zh || investor.fund || investor.style?.length) && (
122+
<Typography variant="body1" sx={{ mt: 1.5, maxWidth: 850, opacity: 0.95 }}>
123+
{investor.intro_zh ||
124+
`风格:${(investor.style || []).slice(0, 4).join(' / ')}${investor.fund ? `;代表:${investor.fund}` : ''}`}
125+
</Typography>
126+
)}
107127

108128
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1 }}>
109129
{investor.style.map(s => (

web/src/components/InvestorList.tsx

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@ function getInitials(investor: Investor) {
3535
return `${parts[0][0]}${parts[parts.length - 1][0]}`.toUpperCase();
3636
}
3737

38+
function buildIntro(investor: Investor) {
39+
if (investor.intro_zh && investor.intro_zh.trim()) return investor.intro_zh.trim();
40+
const style = (investor.style || []).slice(0, 2).join(' / ');
41+
const bestFor = (investor.best_for || []).slice(0, 2).join(' / ');
42+
const fund = investor.fund ? `代表:${investor.fund}` : '';
43+
const parts = [
44+
style ? `风格:${style}` : '',
45+
bestFor ? `擅长:${bestFor}` : '',
46+
fund,
47+
].filter(Boolean);
48+
return parts.join(';');
49+
}
50+
3851
export default function InvestorList({ investors }: { investors: Investor[] }) {
3952
const [search, setSearch] = useState('');
4053
const [missingAvatar, setMissingAvatar] = useState<Record<string, boolean>>({});
@@ -90,9 +103,9 @@ export default function InvestorList({ investors }: { investors: Investor[] }) {
90103
>
91104
{filtered.map((investor) => (
92105
<Box key={investor.id}>
93-
<Card sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
106+
<Card className="imh-card" sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
94107
<CardActionArea component={Link} href={`/investors/${investor.id}`} sx={{ flexGrow: 1 }}>
95-
<CardContent>
108+
<CardContent sx={{ p: 2 }}>
96109
<Stack direction="row" spacing={1.5} alignItems="center" sx={{ mb: 1 }}>
97110
{(() => {
98111
const avatarUrl = getAvatarUrl(investor);
@@ -113,6 +126,7 @@ export default function InvestorList({ investors }: { investors: Investor[] }) {
113126
height: 40,
114127
fontSize: 18,
115128
bgcolor: hashToHsl(investor.id),
129+
border: '1px solid rgba(2,6,23,0.08)',
116130
}}
117131
>
118132
{getInitials(investor)}
@@ -132,8 +146,27 @@ export default function InvestorList({ investors }: { investors: Investor[] }) {
132146
<Typography variant="caption" color="text.secondary" noWrap sx={{ display: 'block' }}>
133147
{investor.full_name}
134148
</Typography>
149+
<Typography variant="caption" color="text.secondary" noWrap sx={{ display: 'block', opacity: 0.9 }}>
150+
{(investor.nationality || '—')}{investor.fund ? ` · ${investor.fund}` : ''}
151+
</Typography>
135152
</Box>
136153
</Stack>
154+
155+
<Typography
156+
variant="body2"
157+
color="text.secondary"
158+
sx={{
159+
mt: 1,
160+
display: '-webkit-box',
161+
WebkitLineClamp: 2,
162+
WebkitBoxOrient: 'vertical',
163+
overflow: 'hidden',
164+
minHeight: 36,
165+
fontSize: 12.5,
166+
}}
167+
>
168+
{buildIntro(investor)}
169+
</Typography>
137170

138171
<Box sx={{ mt: 2, display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
139172
{investor.style.map(s => (

web/src/lib/imh/data.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ export interface Investor {
88
id: string;
99
full_name: string;
1010
chinese_name: string;
11+
nationality?: string;
12+
// Representative company / fund (existing field in investor_index.yaml)
13+
fund?: string;
14+
intro_zh?: string;
1115
style: string[];
1216
best_for: string[];
1317
content?: string;

web/src/theme.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const theme = createTheme({
1010
main: '#fabb05', // Google Yellow
1111
},
1212
background: {
13-
default: '#ffffff',
13+
default: '#f8fafc',
1414
},
1515
},
1616
typography: {
@@ -20,6 +20,8 @@ const theme = createTheme({
2020
'Arial',
2121
'sans-serif',
2222
].join(','),
23+
h4: { letterSpacing: -0.3 },
24+
h3: { letterSpacing: -0.4 },
2325
},
2426
components: {
2527
MuiButton: {
@@ -35,10 +37,25 @@ const theme = createTheme({
3537
root: {
3638
borderRadius: 12,
3739
boxShadow: '0 1px 2px 0 rgba(60,64,67,.30), 0 1px 3px 1px rgba(60,64,67,.15)',
40+
border: '1px solid rgba(2,6,23,0.06)',
41+
transition: 'transform 160ms ease, box-shadow 160ms ease',
42+
},
43+
},
44+
},
45+
MuiCardActionArea: {
46+
styleOverrides: {
47+
root: {
48+
borderRadius: 12,
49+
'&:hover .imh-card': {
50+
transform: 'translateY(-2px)',
51+
boxShadow: '0 10px 25px rgba(2,6,23,0.10)',
52+
},
3853
},
3954
},
4055
},
4156
},
4257
});
4358

4459
export default theme;
60+
61+

0 commit comments

Comments
 (0)