This commit is contained in:
Zylan
2025-04-01 08:44:08 +08:00
parent 98a13f828d
commit c2ef68b33c
3 changed files with 112 additions and 81 deletions

View File

@@ -730,9 +730,10 @@ const translations: Record<Language, Record<string, string>> = {
'share_working_days_per_year': '年工作天数',
'share_hometown_comment': '在家乡工作,让你既能追求事业,又能照顾家人,平衡感满满。家的温暖和熟悉的环境给你带来额外的安全感和幸福感。',
'share_not_hometown_comment': '要照顾好自己,按时吃饭休息,你一个人去得那么远。',
'share_tier1_city_comment': '虽然生活成本较高,但丰富的机会和广阔的平台能够助你更快成长。',
'share_tier2_city_comment': '生活节奏虽然没有一线城市那么快,但依然提供了不错的发展空间。这里的生活压力适中,让你能找到工作与生活之间的平衡。',
'share_tier3_city_comment': '你享受着低成本高质量的生活。虽然机会相对较少,但悠闲的生活节奏和较低的压力让你能更从容地面对人生。要照顾好自己,按时吃饭休息,你一个人去得那么远。',
'share_tier3_city_comment': '你享受着低成本高质量的生活。虽然机会相对较少,但悠闲的生活节奏和较低的压力让你能更从容地面对人生。',
'share_commute_short': '你的通勤时间很短,让你每天都能多出宝贵的时间用于自我提升或休息。',
'share_commute_medium': '你的通勤时间适中,不会让你感到太大压力,也可以利用这段时间听书或补觉。',
@@ -957,6 +958,7 @@ const translations: Record<Language, Record<string, string>> = {
'share_working_days_per_year': 'Working days/year',
'share_hometown_comment': 'Working in your hometown allows you to build your career while maintaining family connections - a valuable balance that contributes to overall life satisfaction.',
'share_not_hometown_comment': 'To take care of yourself, eat and rest on time, you\'re so far away by yourself.',
'share_tier1_city_comment': 'While living costs are high, the abundant opportunities and professional networks in major cities can accelerate your career growth.',
'share_tier2_city_comment': 'This regional center offers a good balance - decent career opportunities with more manageable living costs and work pressure compared to major cities.',
'share_tier3_city_comment': 'You enjoy a good quality of life with lower living costs. While career opportunities may be more limited, the relaxed pace and lower pressure are significant advantages.',
@@ -1183,8 +1185,9 @@ const translations: Record<Language, Record<string, string>> = {
'share_high_value_assessment_3': '理想的な仕事を見つけましたね!このような機会は滅多にありません!',
'share_working_days_per_year': '年間勤務日数',
'share_hometown_comment': '地元で働くことで、キャリアを追求しながら家族とのがり維持できるバランスの取れた生活を送れています。',
'share_tier1_city_comment': '生活費は高いですが、東京などの大都市では豊富な機会とネットワークがあなたのキャリア成長を加速させるでしょう。',
'share_hometown_comment': 'あなたの故郷で働くことで、キャリアを構築しながら家族とのつながり維持することができます - これは総合的な生活満足度に貢献する貴重なバランスです。',
'share_not_hometown_comment': '自分の面倒をしっかり見て、定時に食事と休息を取るように。あなたは一人でとても遠くまで来ました。',
'share_tier1_city_comment': '生活費は高いですが、大都市における豊富な機会と専門的なネットワークはあなたのキャリア成長を加速させることができます。',
'share_tier2_city_comment': '県庁所在地クラスの都市では、適度な機会と比較的落ち着いた生活環境のバランスが取れています。',
'share_tier3_city_comment': '地方都市では生活コストが低く、ゆとりある生活が送れます。キャリア機会は限られるかもしれませんが、ストレスの少ない環境は大きな魅力です。',
@@ -1198,47 +1201,47 @@ const translations: Record<Language, Record<string, string>> = {
'share_cbd_environment': '都心のオフィス環境は専門的かつ近代的で、ビジネスサービスやネットワーキングの機会へのアクセスが容易です。',
'share_factory_environment': '工場や屋外での勤務は独自の課題がありますが、耐久力と実践的な問題解決能力も育てています。',
'share_normal_environment': '職場環境は基本的な設備が整っており、生産的に仕事ができる条件が揃っています。',
'share_leadership_excellent': "Being part of leadership's inner circle offers advantages in terms of opportunities and influence, though it comes with higher expectations.",
'share_leadership_good': 'Your supportive leadership recognizes your contributions and provides the guidance needed for success - a valuable workplace asset.',
'share_leadership_normal': 'Your professional relationship with leadership is straightforward and functional - clear expectations without unnecessary complications.',
'share_leadership_strict': 'Working under strict management can be challenging but often develops discipline and attention to detail that serve you well professionally.',
'share_leadership_bad': 'The tension with leadership creates challenges, requiring careful communication and focusing on deliverables rather than relationships.',
'share_teamwork_excellent': 'The strong personal connections with colleagues creates a supportive network that enhances both work satisfaction and effectiveness.',
'share_teamwork_good': 'Your collaborative team environment fosters mutual support and effective communication, making daily work more pleasant and productive.',
'share_teamwork_normal': 'Maintaining professional but not overly personal relationships with colleagues allows you to focus on your work while having adequate support.',
'share_teamwork_bad': 'The challenging team dynamics require adaptability and self-reliance, which can develop valuable independence and resilience.',
'share_leadership_excellent': "上司の信頼を得ていることで、多くのチャンスと影響力を持つことができますが、同時に高い期待に応える責任も伴います。",
'share_leadership_good': '理解のある上司はあなたの貢献を認め、成功に必要な指導を提供してくれます - これは職場での貴重な財産です。',
'share_leadership_normal': '上司との関係は明快で機能的であり、余計な複雑さなく明確な期待が示されています。',
'share_leadership_strict': '厳格な管理下で働くことは挑戦的ですが、職業人としての規律と細部への注意力を養うことができます。',
'share_leadership_bad': '上司との緊張関係は課題をもたらし、慎重なコミュニケーションと人間関係よりも成果物に焦点を当てる必要があります。',
'share_teamwork_excellent': '同僚との強い個人的なつながりは、仕事の満足度と効率性を高める支援ネットワークを作り出しています。',
'share_teamwork_good': '協力的なチーム環境は相互サポートと効果的なコミュニケーションを促進し、日々の仕事をより快適で生産的にします。',
'share_teamwork_normal': '同僚と専門的でありながら過度に個人的ではない関係を維持することで、十分なサポートを受けながら仕事に集中できます。',
'share_teamwork_bad': '困難なチームダイナミクスには適応力と自立性が求められ、これが貴重な独立性と回復力を育てることがあります。',
'share_workhours_balanced': 'Your balanced work schedule allows sufficient time for personal life, contributing to sustainable long-term performance.',
'share_workhours_long': 'Your extended work hours are manageable but require attention to maintaining energy and preventing burnout.',
'share_workhours_excessive': 'Your work hours are unsustainably long and may impact wellbeing and performance over time. Consider discussing workload adjustments.',
'share_rest_adequate': 'Your generous break time helps maintain energy levels and productivity throughout the workday.',
'share_rest_insufficient': 'Your limited break time suggests a need for incorporating short movement breaks to maintain health and focus.',
'share_leave_abundant': 'Your generous leave allowance provides ample time for rejuvenation and personal pursuits - essential for sustained motivation.',
'share_leave_limited': 'With limited leave time, strategic planning of your days off becomes important for maximizing their restorative benefit.',
'share_workhours_balanced': 'バランスの取れた勤務スケジュールは、個人生活のための十分な時間を確保し、長期的な持続可能なパフォーマンスに貢献します。',
'share_workhours_long': '長時間の勤務は管理可能ですが、エネルギーを維持し燃え尽き症候群を防ぐための注意が必要です。',
'share_workhours_excessive': '持続不可能なほど長い勤務時間は、長期的に健康とパフォーマンスに影響を与える可能性があります。業務量の調整について話し合うことを検討してください。',
'share_rest_adequate': '十分な休憩時間は、一日を通してエネルギーレベルと生産性を維持するのに役立ちます。',
'share_rest_insufficient': '限られた休憩時間は、健康と集中力を維持するために短い運動休憩を取り入れる必要性を示唆しています。',
'share_leave_abundant': '充実した休暇制度は、リフレッシュと個人的な追求のための十分な時間を提供し、持続的なモチベーションに不可欠です。',
'share_leave_limited': '限られた休暇時間では、その回復効果を最大化するために休日の戦略的な計画が重要になります。',
'share_phd_comment': 'Your doctoral qualification opens doors to specialized positions and demonstrates advanced research and analytical capabilities.',
'share_masters_comment': "Your master's degree demonstrates advanced knowledge and commitment that remains valuable in today's competitive job market.",
'share_bachelor_comment': "Your bachelor's degree provides a solid foundation that, combined with practical experience, enables diverse career opportunities.",
'share_below_bachelor_comment': "While formal education below bachelor's level may present challenges in some fields, practical skills and experience can be equally valuable assets.",
'share_fresh_graduate_comment': 'As a recent graduate, your fresh perspective and current knowledge are assets, balanced by the unlimited potential for growth and learning.',
'share_experienced_comment': 'Your substantial work experience provides valuable context and judgment that enhance your effectiveness and confidence.',
'share_mid_career_comment': 'With several years of experience, you understand both your industry and personal strengths, positioning you for strategic career development.',
'share_government_job_comment': 'The stability of public sector employment reduces career uncertainty, allowing more confident long-term planning.',
'share_private_job_comment': 'While private sector employment carries some uncertainty, it often provides accelerated growth and compensation opportunities.',
'share_phd_comment': '博士号の資格は専門的なポジションへの道を開き、高度な研究と分析能力を証明します。',
'share_masters_comment': "修士号は高度な知識と献身を示し、今日の競争の激しい就職市場で価値ある資格です。",
'share_bachelor_comment': "学士号は堅実な基盤を提供し、実践的な経験と組み合わせることで、多様なキャリア機会を可能にします。",
'share_below_bachelor_comment': "学士未満の正式な教育は一部の分野で課題をもたらす可能性がありますが、実践的なスキルと経験は同様に価値ある資産となります。",
'share_fresh_graduate_comment': '新卒者として、あなたの新鮮な視点と最新の知識は資産であり、成長と学習のための無限の可能性とバランスを取ることができます。',
'share_experienced_comment': '豊富な職務経験は、あなたの効果と自信を高める貴重な文脈と判断力を提供します。',
'share_mid_career_comment': '数年の経験を持つあなたは、業界と個人の強みの両方を理解し、戦略的なキャリア開発の準備ができています。',
'share_government_job_comment': '公共部門の雇用の安定性はキャリアの不確実性を軽減し、より自信を持って長期的な計画を立てることができます。',
'share_private_job_comment': '民間部門の雇用にはある程度の不確実性がありますが、多くの場合、加速された成長と報酬の機会を提供します。',
'share_salary_high_cny': 'Your daily compensation is competitive, providing financial security and flexibility for both necessities and discretionary spending.',
'share_salary_medium_cny': 'Your compensation meets basic needs comfortably but requires thoughtful budgeting for optimal financial health.',
'share_salary_low_cny': 'Your current compensation level necessitates careful financial management while you explore opportunities for income growth.',
'share_salary_high_foreign': 'Your daily compensation is competitive, providing financial security and flexibility for both necessities and discretionary spending.',
'share_salary_medium_foreign': 'Your compensation meets basic needs comfortably but requires thoughtful budgeting for optimal financial health.',
'share_salary_low_foreign': 'Your current compensation level necessitates careful financial management while you explore opportunities for income growth.',
'share_high_cost_city': 'In a high-cost location, careful financial planning helps maximize the value of your compensation.',
'share_low_cost_city': 'In a lower-cost area, your compensation provides enhanced purchasing power and potential for savings.',
'share_salary_high_cny': '日給が競争力があり、必需品と自由裁量の支出の両方に対して財政的安定性と柔軟性を提供します。',
'share_salary_medium_cny': '給与は基本的なニーズを快適に満たしていますが、最適な財政状態のために思慮深い予算計画が必要です。',
'share_salary_low_cny': '現在の給与水準では、収入増加の機会を探りながら、慎重な財務管理が必要です。',
'share_salary_high_foreign': '日給が競争力があり、必需品と自由裁量の支出の両方に対して財政的安定性と柔軟性を提供します。',
'share_salary_medium_foreign': '給与は基本的なニーズを快適に満たしていますが、最適な財政状態のために思慮深い予算計画が必要です。',
'share_salary_low_foreign': '現在の給与水準では、収入増加の機会を探りながら、慎重な財務管理が必要です。',
'share_high_cost_city': '生活費の高い地域では、慎重な財務計画が報酬の価値を最大化するのに役立ちます。',
'share_low_cost_city': '生活費の低い地域では、給与がより高い購買力と貯蓄の可能性をもたらします。',
'share_value_low': 'While the current position shows limited value, it may provide necessary experience for future growth. Extract learning from every aspect while preparing for your next career move.',
'share_value_medium': 'Your job offers balanced value with both strengths and areas for improvement. Focus on leveraging the positive aspects while developing strategies to address the challenges.',
'share_value_high': "You've found a high-value position worth maintaining and developing. Continue building on your strengths and appreciate the satisfaction this role provides.",
'share_summary_advice': 'Overall Recommendation',
'share_value_low': '現在の仕事の価値は限られているかもしれませんが、将来の成長に必要な経験を提供するかもしれません。次のキャリアステップの準備をしながら、すべての側面から学びを得ることが大切です。',
'share_value_medium': 'あなたの仕事は長所と改善すべき点の両方があるバランスのとれた価値を提供しています。ポジティブな側面を活かしながら、課題に対処するための戦略を立てましょう。',
'share_value_high': '維持・発展させる価値のある高価値の職場を見つけました。あなたの強みを引き続き伸ばし、この役割が提供する満足感を大切にしましょう。',
'share_summary_advice': '総合的なアドバイス',
// 評価
'rating_enter_salary': '給与を入力してください',

View File

@@ -252,17 +252,23 @@ const ShareCard: React.FC<ShareCardProps> = (props) => {
const cityName = getCityName(props.cityFactor, t);
const isHomeTown = props.homeTown === 'yes';
let cityComment = "";
if (isHomeTown) {
cityComment = t('share_hometown_comment');
// 先根据城市等级添加评价
if (props.cityFactor === '0.70' || props.cityFactor === '0.80') {
cityComment = t('share_tier1_city_comment');
} else if (props.cityFactor === '1.0' || props.cityFactor === '1.10') {
cityComment = t('share_tier2_city_comment');
} else {
if (props.cityFactor === '0.70' || props.cityFactor === '0.80') {
cityComment = t('share_tier1_city_comment');
} else if (props.cityFactor === '1.0' || props.cityFactor === '1.10') {
cityComment = t('share_tier2_city_comment');
} else {
cityComment = t('share_tier3_city_comment');
}
cityComment = t('share_tier3_city_comment');
}
// 然后添加家乡相关评价
if (isHomeTown) {
cityComment += " " + t('share_hometown_comment');
} else {
cityComment += " " + t('share_not_hometown_comment');
}
comments.push({
title: t('share_work_city'),
content: cityComment,
@@ -508,6 +514,21 @@ const ShareCard: React.FC<ShareCardProps> = (props) => {
return comments;
})();
// 是否是移动设备(响应式设计辅助函数)
const [isMobile, setIsMobile] = useState(false);
// 检测设备类型
useEffect(() => {
if (typeof window !== 'undefined') {
const checkMobile = () => {
setIsMobile(window.innerWidth < 640);
};
checkMobile();
window.addEventListener('resize', checkMobile);
return () => window.removeEventListener('resize', checkMobile);
}
}, []);
// 处理下载图片 - 使用简化版报告
const handleDownload = async () => {
if (!simpleReportRef.current || isDownloading) return;
@@ -561,47 +582,54 @@ const ShareCard: React.FC<ShareCardProps> = (props) => {
return (
<div className={`min-h-screen bg-gradient-to-br ${getBackground()} flex flex-col items-center justify-start p-4 md:p-8 transition-opacity duration-1000 ${fadeIn ? 'opacity-100' : 'opacity-0'} dark:text-white`}>
{/* 返回按钮 */}
<div className="w-full max-w-4xl mb-6">
<Link href="/" className="flex items-center gap-2 text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white transition-colors">
<ArrowLeft className="w-4 h-4" />
<div className="w-full max-w-4xl mb-4 md:mb-6">
<Link href="/" className="flex items-center gap-1.5 text-sm text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white transition-colors">
<ArrowLeft className="w-3.5 h-3.5" />
<span>{t('share_back_to_calculator')}</span>
</Link>
</div>
<div ref={reportRef} className="w-full max-w-4xl bg-white rounded-xl shadow-xl p-6 md:p-10">
{/* 标题 */}
<div className="mb-10 text-center">
<div className="text-6xl mb-4">{isClient ? getEmoji(parseFloat(props.value)) : '😊'}</div>
<h1 className="text-3xl md:text-4xl font-bold mb-3 bg-clip-text text-transparent bg-gradient-to-r from-blue-600 to-purple-600">
<div ref={reportRef} className="w-full max-w-4xl bg-white rounded-xl shadow-xl p-4 md:p-10">
{/* 标题 - 移动端更紧凑 */}
<div className="mb-5 md:mb-10 text-center">
<div className="text-4xl md:text-6xl mb-2 md:mb-4">{isClient ? getEmoji(parseFloat(props.value)) : '😊'}</div>
<h1 className="text-xl md:text-3xl font-bold mb-2 md:mb-3 bg-clip-text text-transparent bg-gradient-to-r from-blue-600 to-purple-600">
{t('share_your_job_worth_report')}
</h1>
<div className="flex justify-center items-center gap-3">
<span className="text-2xl font-bold px-3 py-1 rounded-lg" style={{ color: getColorFromClassName(props.assessmentColor), backgroundColor: `${getColorFromClassName(props.assessmentColor)}20` }}>
<div className="flex justify-center items-center gap-2">
<span className="text-lg md:text-2xl font-bold px-2 py-0.5 rounded-lg" style={{ color: getColorFromClassName(props.assessmentColor), backgroundColor: `${getColorFromClassName(props.assessmentColor)}20` }}>
{props.value}
</span>
<span className="text-lg text-gray-700">{isClient ? t(getAssessmentKey(props.assessment)) : ''}</span>
<span className="text-base md:text-lg text-gray-700">{isClient ? t(getAssessmentKey(props.assessment)) : ''}</span>
</div>
</div>
{/* 性价比评语卡片 */}
<div className="space-y-8">
{/* 性价比评语卡片 - 移动端更紧凑 */}
<div className="space-y-4 md:space-y-6">
{isClient && personalizedComments.map((comment, index) => (
<div key={index} className="bg-gradient-to-r from-gray-50 to-gray-100 rounded-xl p-6 shadow-md transition-all hover:shadow-lg">
<div className="flex items-start gap-4">
<div className="text-4xl flex-shrink-0">{comment.emoji}</div>
<div key={index} className="bg-gradient-to-r from-gray-50 to-gray-100 rounded-lg md:rounded-xl p-3 md:p-5 shadow-sm transition-all hover:shadow-md">
<div className="flex items-start gap-2.5 md:gap-4">
<div className="text-2xl md:text-4xl flex-shrink-0 mt-0.5">{comment.emoji}</div>
<div className="flex-1">
<h3 className="text-xl font-bold mb-2 text-gray-800">{comment.title}</h3>
<p className="text-gray-700 leading-relaxed mb-4">{comment.content}</p>
<h3 className="text-base md:text-lg font-bold mb-1 md:mb-2 text-gray-800">{comment.title}</h3>
<p className="text-xs md:text-sm text-gray-700 leading-relaxed mb-2 md:mb-3">{comment.content}</p>
{/* 用户选项详情 */}
{/* 用户选项详情 - 移动端使用行内排列 */}
{comment.details && comment.details.length > 0 && (
<div className="mt-3 pt-3 border-t border-gray-200">
<div className="grid grid-cols-2 gap-2">
<div className="mt-2 pt-2 border-t border-gray-200">
<div className={isMobile ? "flex flex-wrap gap-x-4 gap-y-1.5" : "grid grid-cols-2 gap-2"}>
{comment.details.map((detail, i) => (
<div key={i} className="flex flex-col">
<span className="text-xs text-gray-500">{detail.label}</span>
<span className="text-sm font-medium text-gray-800">{detail.value}</span>
</div>
isMobile ? (
<div key={i} className="flex items-center text-xs">
<span className="text-gray-500 mr-1">{detail.label}:</span>
<span className="font-medium text-gray-800">{detail.value}</span>
</div>
) : (
<div key={i} className="flex justify-between items-center">
<span className="text-xs text-gray-500">{detail.label}</span>
<span className="text-xs md:text-sm font-medium text-gray-800">{detail.value}</span>
</div>
)
))}
</div>
</div>
@@ -612,21 +640,21 @@ const ShareCard: React.FC<ShareCardProps> = (props) => {
))}
</div>
{/* 底部信息 */}
<div className="mt-10 text-center text-gray-500 space-y-1">
{/* 底部信息 - 更小的文字 */}
<div className="mt-6 md:mt-10 text-center text-gray-500 space-y-0.5 text-xs md:text-sm">
<div>{t('share_custom_made')}</div>
<div>worthjob.zippland.com</div>
</div>
</div>
{/* 操作按钮 */}
<div className="flex justify-center gap-4 mt-8">
{/* 操作按钮 - 更小的按钮 */}
<div className="flex justify-center gap-4 mt-4 md:mt-8">
<button
onClick={handleDownload}
disabled={isDownloading}
className="flex items-center gap-2 px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white rounded-lg shadow-md transition-colors"
className="flex items-center gap-1.5 px-4 py-2 md:px-6 md:py-3 bg-blue-600 hover:bg-blue-700 text-white text-sm md:text-base rounded-lg shadow-md transition-colors"
>
<Download className="w-5 h-5" />
<Download className="w-4 h-4 md:w-5 md:h-5" />
{isDownloading ? t('share_generating') : t('share_download_report')}
</button>
</div>

View File

@@ -747,7 +747,7 @@ const SalaryCalculator = () => {
</div>
<div className="flex items-center justify-center gap-3 mb-2">
<p className="text-sm text-gray-500 dark:text-gray-400">v5.3.1</p>
<p className="text-sm text-gray-500 dark:text-gray-400">v5.4.1</p>
<a
href="https://github.com/zippland/worth-calculator"
target="_blank"