зеркало из
https://github.com/kodackx/disinformation-quest.git
synced 2025-10-29 12:46:03 +02:00
layout upgrades
Этот коммит содержится в:
родитель
1dfc34d0c4
Коммит
d373d95c9b
@ -23,6 +23,7 @@ interface ExpertMemoProps {
|
||||
isAlert?: boolean;
|
||||
stage?: string;
|
||||
audioRef?: React.RefObject<HTMLAudioElement>;
|
||||
onStrategyClick?: (choiceNumber: number) => void;
|
||||
}
|
||||
|
||||
export const ExpertMemo: React.FC<ExpertMemoProps> = ({
|
||||
@ -31,7 +32,8 @@ export const ExpertMemo: React.FC<ExpertMemoProps> = ({
|
||||
children,
|
||||
isAlert = false,
|
||||
stage,
|
||||
audioRef
|
||||
audioRef,
|
||||
onStrategyClick
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const [showGradient, setShowGradient] = useState(false);
|
||||
|
||||
@ -77,7 +77,7 @@ export const IntroDialog = ({ onStartAudio }: IntroDialogProps) => {
|
||||
<Dialog open={open}>
|
||||
<DialogContent
|
||||
ref={contentRef}
|
||||
className="[&>button]:hidden bg-black/95 text-white border-gray-700 max-w-4xl max-h-[90vh] overflow-y-auto p-0 relative text-center fixed top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]"
|
||||
className="[&>button]:hidden bg-black/95 text-white border-gray-700 max-w-3xl max-h-[90vh] overflow-y-auto p-0 relative text-center fixed top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]"
|
||||
>
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-yellow-500/10 to-transparent pointer-events-none" />
|
||||
<div className="absolute inset-0 bg-[url('/images/noise.png')] opacity-[0.03] pointer-events-none" />
|
||||
@ -130,23 +130,23 @@ export const IntroDialog = ({ onStartAudio }: IntroDialogProps) => {
|
||||
<p className="text-xs sm:text-sm leading-relaxed text-rendering-optimizeLegibility">
|
||||
{t('intro.howToPlay.description')}
|
||||
</p>
|
||||
<div className="grid grid-cols-3 gap-2 mt-1">
|
||||
<div className="flex flex-col items-center gap-1 bg-yellow-500/5 p-2 rounded-md">
|
||||
<Calendar className="h-4 w-4 text-yellow-500" />
|
||||
<span className="text-xs text-center">{t('intro.howToPlay.features.monthlyBriefings')}</span>
|
||||
<div className="grid grid-cols-3 gap-6 mt-4 px-4">
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<Calendar className="h-6 w-6 text-yellow-500" />
|
||||
<span className="text-xs text-center text-gray-300">{t('intro.howToPlay.features.monthlyBriefings')}</span>
|
||||
</div>
|
||||
<div className="flex flex-col items-center gap-1 bg-yellow-500/5 p-2 rounded-md">
|
||||
<TrendingUp className="h-4 w-4 text-yellow-500" />
|
||||
<span className="text-xs text-center">{t('intro.howToPlay.features.trackProgress')}</span>
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<TrendingUp className="h-6 w-6 text-yellow-500" />
|
||||
<span className="text-xs text-center text-gray-300">{t('intro.howToPlay.features.trackProgress')}</span>
|
||||
</div>
|
||||
<div className="flex flex-col items-center gap-1 bg-yellow-500/5 p-2 rounded-md">
|
||||
<Target className="h-4 w-4 text-yellow-500" />
|
||||
<span className="text-xs text-center">{t('intro.howToPlay.features.strategicChoices')}</span>
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<Target className="h-6 w-6 text-yellow-500" />
|
||||
<span className="text-xs text-center text-gray-300">{t('intro.howToPlay.features.strategicChoices')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
{/* <motion.div
|
||||
className="flex items-center gap-2 bg-yellow-500/10 p-2 sm:p-3 rounded-lg border border-yellow-500/20"
|
||||
variants={itemVariants}
|
||||
>
|
||||
@ -154,7 +154,7 @@ export const IntroDialog = ({ onStartAudio }: IntroDialogProps) => {
|
||||
<p className="text-xs sm:text-sm text-yellow-500 drop-shadow">
|
||||
{t('intro.reminder')}
|
||||
</p>
|
||||
</motion.div>
|
||||
</motion.div> */}
|
||||
</div>
|
||||
</DialogHeader>
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ import { GameStage } from "../types";
|
||||
import { ExpertMemo } from '../ExpertMemo';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ChoiceID } from './metrics';
|
||||
import { ChevronRightIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
export const STAGE_CHOICES = [
|
||||
[ChoiceID.DEPLOY_BOTS, ChoiceID.ESTABLISH_MEMES], // January
|
||||
@ -17,7 +18,10 @@ export const STAGE_CHOICES = [
|
||||
] as const;
|
||||
|
||||
// Create a custom hook to handle stages with translations
|
||||
export const useGameStages = (audioRef: React.RefObject<HTMLAudioElement>): GameStage[] => {
|
||||
export const useGameStages = (
|
||||
audioRef: React.RefObject<HTMLAudioElement>,
|
||||
onStrategyClick?: (stage: number, choiceNumber: number) => void
|
||||
): GameStage[] => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
// Helper function to get translated month title
|
||||
@ -42,14 +46,30 @@ export const useGameStages = (audioRef: React.RefObject<HTMLAudioElement>): Game
|
||||
from={t('stages.1.expertMemo.from')}
|
||||
subject={t('stages.1.expertMemo.subject')}
|
||||
stage="1"
|
||||
audioRef={audioRef}>
|
||||
audioRef={audioRef}
|
||||
onStrategyClick={(choice) => onStrategyClick?.(1, choice)}
|
||||
>
|
||||
<p>{t('stages.1.expertMemo.content.greeting')}</p>
|
||||
|
||||
<p>{t('stages.1.expertMemo.content.intro')}</p>
|
||||
|
||||
<p>{t('stages.1.expertMemo.content.strategy1')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(1, 1)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 1:</span> {t('stages.1.choices.1.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.1.expertMemo.content.strategy2')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(1, 2)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 2:</span> {t('stages.1.choices.2.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.1.expertMemo.content.conclusion')}</p>
|
||||
|
||||
@ -121,14 +141,30 @@ export const useGameStages = (audioRef: React.RefObject<HTMLAudioElement>): Game
|
||||
from={t('stages.2.expertMemo.from')}
|
||||
subject={t('stages.2.expertMemo.subject')}
|
||||
stage="2"
|
||||
audioRef={audioRef}>
|
||||
audioRef={audioRef}
|
||||
onStrategyClick={(choice) => onStrategyClick?.(2, choice)}
|
||||
>
|
||||
<p>{t('stages.2.expertMemo.content.greeting')}</p>
|
||||
|
||||
<p>{t('stages.2.expertMemo.content.intro')}</p>
|
||||
|
||||
<p>{t('stages.2.expertMemo.content.strategy1')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(2, 1)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 1:</span> {t('stages.2.choices.1.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.2.expertMemo.content.strategy2')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(2, 2)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 2:</span> {t('stages.2.choices.2.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.2.expertMemo.content.conclusion')}</p>
|
||||
|
||||
@ -198,14 +234,30 @@ export const useGameStages = (audioRef: React.RefObject<HTMLAudioElement>): Game
|
||||
from={t('stages.3.expertMemo.from')}
|
||||
subject={t('stages.3.expertMemo.subject')}
|
||||
stage="3"
|
||||
audioRef={audioRef}>
|
||||
audioRef={audioRef}
|
||||
onStrategyClick={(choice) => onStrategyClick?.(3, choice)}
|
||||
>
|
||||
<p>{t('stages.3.expertMemo.content.greeting')}</p>
|
||||
|
||||
<p>{t('stages.3.expertMemo.content.intro')}</p>
|
||||
|
||||
<p>{t('stages.3.expertMemo.content.strategy1')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(3, 1)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 1:</span> {t('stages.3.choices.1.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.3.expertMemo.content.strategy2')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(3, 2)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 2:</span> {t('stages.3.choices.2.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.3.expertMemo.content.conclusion')}</p>
|
||||
|
||||
@ -277,14 +329,30 @@ export const useGameStages = (audioRef: React.RefObject<HTMLAudioElement>): Game
|
||||
subject={t('stages.4.expertMemo.subject')}
|
||||
isAlert={true}
|
||||
stage="4"
|
||||
audioRef={audioRef}>
|
||||
audioRef={audioRef}
|
||||
onStrategyClick={(choice) => onStrategyClick?.(4, choice)}
|
||||
>
|
||||
<p>{t('stages.4.expertMemo.content.greeting')}</p>
|
||||
|
||||
<p>{t('stages.4.expertMemo.content.intro')}</p>
|
||||
|
||||
<p>{t('stages.4.expertMemo.content.strategy1')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(4, 1)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 1:</span> {t('stages.4.choices.1.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.4.expertMemo.content.strategy2')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(4, 2)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 2:</span> {t('stages.4.choices.2.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.4.expertMemo.content.conclusion')}</p>
|
||||
|
||||
@ -355,14 +423,30 @@ export const useGameStages = (audioRef: React.RefObject<HTMLAudioElement>): Game
|
||||
from={t('stages.5.expertMemo.from')}
|
||||
subject={t('stages.5.expertMemo.subject')}
|
||||
stage="5"
|
||||
audioRef={audioRef}>
|
||||
audioRef={audioRef}
|
||||
onStrategyClick={(choice) => onStrategyClick?.(5, choice)}
|
||||
>
|
||||
<p>{t('stages.5.expertMemo.content.greeting')}</p>
|
||||
|
||||
<p>{t('stages.5.expertMemo.content.intro')}</p>
|
||||
|
||||
<p>{t('stages.5.expertMemo.content.strategy1')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(5, 1)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 1:</span> {t('stages.5.choices.1.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.5.expertMemo.content.strategy2')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(5, 2)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 2:</span> {t('stages.5.choices.2.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.5.expertMemo.content.conclusion')}</p>
|
||||
|
||||
@ -433,14 +517,30 @@ export const useGameStages = (audioRef: React.RefObject<HTMLAudioElement>): Game
|
||||
from={t('stages.6.expertMemo.from')}
|
||||
subject={t('stages.6.expertMemo.subject')}
|
||||
stage="6"
|
||||
audioRef={audioRef}>
|
||||
audioRef={audioRef}
|
||||
onStrategyClick={(choice) => onStrategyClick?.(6, choice)}
|
||||
>
|
||||
<p>{t('stages.6.expertMemo.content.greeting')}</p>
|
||||
|
||||
<p>{t('stages.6.expertMemo.content.intro')}</p>
|
||||
|
||||
<p>{t('stages.6.expertMemo.content.strategy1')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(6, 1)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 1:</span> {t('stages.6.choices.1.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.6.expertMemo.content.strategy2')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(6, 2)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 2:</span> {t('stages.6.choices.2.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.6.expertMemo.content.conclusion')}</p>
|
||||
|
||||
@ -511,14 +611,30 @@ export const useGameStages = (audioRef: React.RefObject<HTMLAudioElement>): Game
|
||||
from={t('stages.7.expertMemo.from')}
|
||||
subject={t('stages.7.expertMemo.subject')}
|
||||
stage="7"
|
||||
audioRef={audioRef}>
|
||||
audioRef={audioRef}
|
||||
onStrategyClick={(choice) => onStrategyClick?.(7, choice)}
|
||||
>
|
||||
<p>{t('stages.7.expertMemo.content.greeting')}</p>
|
||||
|
||||
<p>{t('stages.7.expertMemo.content.intro')}</p>
|
||||
|
||||
<p>{t('stages.7.expertMemo.content.strategy1')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(7, 1)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 1:</span> {t('stages.7.choices.1.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.7.expertMemo.content.strategy2')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(7, 2)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 2:</span> {t('stages.7.choices.2.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.7.expertMemo.content.conclusion')}</p>
|
||||
|
||||
@ -589,14 +705,30 @@ export const useGameStages = (audioRef: React.RefObject<HTMLAudioElement>): Game
|
||||
from={t('stages.8.expertMemo.from')}
|
||||
subject={t('stages.8.expertMemo.subject')}
|
||||
stage="8"
|
||||
audioRef={audioRef}>
|
||||
audioRef={audioRef}
|
||||
onStrategyClick={(choice) => onStrategyClick?.(8, choice)}
|
||||
>
|
||||
<p>{t('stages.8.expertMemo.content.greeting')}</p>
|
||||
|
||||
<p>{t('stages.8.expertMemo.content.intro')}</p>
|
||||
|
||||
<p>{t('stages.8.expertMemo.content.strategy1')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(8, 1)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 1:</span> {t('stages.8.choices.1.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.8.expertMemo.content.strategy2')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(8, 2)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 2:</span> {t('stages.8.choices.2.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.8.expertMemo.content.conclusion')}</p>
|
||||
|
||||
@ -668,14 +800,30 @@ export const useGameStages = (audioRef: React.RefObject<HTMLAudioElement>): Game
|
||||
subject={t('stages.9.expertMemo.subject')}
|
||||
stage="9"
|
||||
isAlert={true}
|
||||
audioRef={audioRef}>
|
||||
audioRef={audioRef}
|
||||
onStrategyClick={(choice) => onStrategyClick?.(9, choice)}
|
||||
>
|
||||
<p>{t('stages.9.expertMemo.content.greeting')}</p>
|
||||
|
||||
<p>{t('stages.9.expertMemo.content.intro')}</p>
|
||||
|
||||
<p>{t('stages.9.expertMemo.content.strategy1')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(9, 1)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 1:</span> {t('stages.9.choices.1.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.9.expertMemo.content.strategy2')}</p>
|
||||
<p
|
||||
className="cursor-pointer hover:text-yellow-400 transition-colors flex items-center gap-2 group border border-yellow-500/30 hover:border-yellow-500/50 rounded px-3 py-2 hover:bg-yellow-500/5"
|
||||
onClick={() => onStrategyClick?.(9, 2)}
|
||||
>
|
||||
<ChevronRightIcon className="w-4 h-4 text-yellow-500 group-hover:translate-x-1 transition-transform" />
|
||||
<span className="text-yellow-500">Option 2:</span> {t('stages.9.choices.2.text')}
|
||||
<span className="text-gray-500 text-sm ml-2">({t('common.clickForDetails')})</span>
|
||||
</p>
|
||||
|
||||
<p>{t('stages.9.expertMemo.content.conclusion')}</p>
|
||||
|
||||
|
||||
@ -85,7 +85,7 @@
|
||||
"explanation": "While this may seem absurd, the techniques you'll encounter mirror real-world disinformation tactics. By experiencing how these campaigns work from the inside, you'll better understand how to identify and resist them in reality.",
|
||||
"howToPlay": {
|
||||
"title": "How to Play",
|
||||
"description": "You will progress through a year-long simulation where you'll make strategic choices on how to invest your resources. Each month, you'll analyze expert briefings and choose between different strategies. Your decisions will affect your campaign's reach, supporter loyalty, and viral spread. Track your progress in the mission dossier and adapt your approach based on results.",
|
||||
"description": "Progress through a year-long simulation, making strategic choices each month. Review expert briefings, track your progress, and adapt your approach based on results.",
|
||||
"features": {
|
||||
"monthlyBriefings": "Monthly Briefings",
|
||||
"trackProgress": "Track Progress",
|
||||
@ -802,5 +802,9 @@
|
||||
"showLess": "Show Less",
|
||||
"learnMore": "Real-World Examples",
|
||||
"readArticle": "Read Article"
|
||||
},
|
||||
"common": {
|
||||
"loading": "Loading...",
|
||||
"clickForDetails": "click for details"
|
||||
}
|
||||
}
|
||||
@ -85,7 +85,7 @@
|
||||
"explanation": "Deși poate părea absurd, tehnicile pe care le vei întâlni reflectă tacticile de dezinformare din lumea reală. Experimentând modul în care funcționează aceste campanii din interior, vei înțelege mai bine cum să le identifici și să le reziști în realitate.",
|
||||
"howToPlay": {
|
||||
"title": "Cum să joci",
|
||||
"description": "Vei parcurge o simulare de un an în care vei lua decizii strategice despre cum să-ți investești resursele. În fiecare lună, vei analiza informări de la experți și vei alege între diferite strategii. Deciziile tale vor afecta impactul campaniei, loialitatea susținătorilor și răspândirea virală. Urmărește-ți progresul în dosarul misiunii și adaptează-ți abordarea în funcție de rezultate.",
|
||||
"description": "Parcurge o simulare de un an, luând decizii strategice în fiecare lună. Analizează briefing-urile experților, urmărește-ți progresul și adaptează-ți abordarea în funcție de rezultate.",
|
||||
"features": {
|
||||
"monthlyBriefings": "Briefing-uri Lunare",
|
||||
"trackProgress": "Urmărește Progresul",
|
||||
@ -802,5 +802,9 @@
|
||||
"showLess": "Arată mai puțin",
|
||||
"learnMore": "Exemple din lumea reală",
|
||||
"readArticle": "Citește articolul"
|
||||
},
|
||||
"common": {
|
||||
"loading": "Se încarcă...",
|
||||
"clickForDetails": "click pentru detalii"
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +47,16 @@ const Index = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const audioRef = useRef<HTMLAudioElement | null>(null);
|
||||
const [previousChoices, setPreviousChoices] = useState<ChoiceID[]>([]);
|
||||
const stages = useGameStages(audioRef);
|
||||
const stages = useGameStages(audioRef, (stage, choice) => {
|
||||
// Find the stage and choice
|
||||
const currentStageData = stages[stage - 1];
|
||||
if (currentStageData) {
|
||||
const selectedChoice = currentStageData.choices[choice - 1];
|
||||
if (selectedChoice) {
|
||||
handleStrategyClick(selectedChoice);
|
||||
}
|
||||
}
|
||||
});
|
||||
const operationNameKey = OPERATION_NAMES[Math.floor(Math.random() * OPERATION_NAMES.length)];
|
||||
const operationName = t(`operations.${operationNameKey}`);
|
||||
const [agentNumber] = useState(Math.floor(Math.random() * 999).toString().padStart(3, '0'));
|
||||
@ -603,7 +612,7 @@ const Index = () => {
|
||||
</CardDescription>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
{/* <CardContent className="space-y-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{(() => {
|
||||
console.log('Index - Rendering stage:', currentStage);
|
||||
@ -619,7 +628,7 @@ const Index = () => {
|
||||
));
|
||||
})()}
|
||||
</div>
|
||||
</CardContent>
|
||||
</CardContent> */}
|
||||
<div className="mt-4 border-t border-gray-700/50">
|
||||
<div className="flex justify-center py-4">
|
||||
<LanguageSwitcher />
|
||||
|
||||
Загрузка…
x
Ссылка в новой задаче
Block a user