CoolFace
Apppublic

Mistral-AI-Game-Jam/DefendDaniel2

sourceHugging Faceupdated 2y agoView on Hugging Face
7likes
page.tsx261 linesDownload Raw Back to app
1// /$$$$$$  /$$$$$$ /$$    /$$ /$$$$$$$$       /$$      /$$ /$$$$$$$$        /$$$$$$           /$$$$$  /$$$$$$  /$$$$$$$ 2// /$$__  $$|_  $$_/| $$   | $$| $$_____/      | $$$    /$$$| $$_____/       /$$__  $$         |__  $$ /$$__  $$| $$__  $$3// | $$  \__/  | $$  | $$   | $$| $$            | $$$$  /$$$$| $$            | $$  \ $$            | $$| $$  \ $$| $$  \ $$4// | $$ /$$$$  | $$  |  $$ / $$/| $$$$$         | $$ $$/$$ $$| $$$$$         | $$$$$$$$            | $$| $$  | $$| $$$$$$$ 5// | $$|_  $$  | $$   \  $$ $$/ | $$__/         | $$  $$$| $$| $$__/         | $$__  $$       /$$  | $$| $$  | $$| $$__  $$6// | $$  \ $$  | $$    \  $$$/  | $$            | $$\  $ | $$| $$            | $$  | $$      | $$  | $$| $$  | $$| $$  \ $$7// |  $$$$$$/ /$$$$$$   \  $/   | $$$$$$$$      | $$ \/  | $$| $$$$$$$$      | $$  | $$      |  $$$$$$/|  $$$$$$/| $$$$$$$/8// \______/ |______/    \_/    |________/      |__/     |__/|________/      |__/  |__/       \______/  \______/ |_______/ 9//10// Hi, I'm Roland and i'm looking for a job.11// Resume in /public/resume.pdf12// roland.vrignon@roland.com13// https://www.linkedin.com/in/roland-vrignon/14//15 16'use client';17 18import { useState, useEffect } from 'react';19import MenuScene from '../components/menu/Menu';20import IntroScene from '../components/intro/Intro';21import CourtScene from '../components/court/Court';22import DefenseScene from '../components/defense/Defense';23import LawyerScene from '../components/lawyer/Lawyer';24import EndScene from '../components/end/End';25import AccusationScene from '../components/accusation/Accusation';26 27// Types pour notre état28type Language = 'fr' | 'en' | 'es';29 30type Scene = 'menu' | 'intro' | 'accusation' | 'court' | 'defense' | 'lawyer' | 'end';31interface Story {32  accusation: {33    description: string;34    alibi: string[];35  };36}37 38interface Message {39  content: string;40  role: 'lawyer' | 'judge';41  requiredWords?: string[];42}43 44interface Chat {45  messages: Message[];46}47 48interface Verdict {49  verdict: boolean;50  argument: string;51  prisonYears: number;52}53 54const intro = {55  fr: {56    title: "L'Avocat de l'IA",57    description: `Daniel est un mec banale. Il n'a rien fait de mal.\nPourtant, il est convoqué aujourd'hui dans ce tribunal. Pauvre Daniel...`,58    start: "Commencer"59  },60  en: {61    title: "The AI Lawyer", 62    description: `Daniel is an ordinary guy. He hasn't done anything wrong.\nYet he's been summoned to court today. Poor Daniel...`,63    start: "Start"64  },65  es: {66    title: "El Abogado de la IA",67    description: `Daniel es un tipo corriente. No ha hecho nada malo.\nSin embargo, ha sido convocado a la corte hoy. Pobre Daniel...`,68    start: "Empezar"69  }70}71 72const sceneOrder: Scene[] = ['menu', 'intro', 'accusation', 'court', 'defense', 'lawyer'];73 74export default function Home() {75  // Gestion des scènes76  const [currentScene, setCurrentScene] = useState<Scene>('menu');77  const [story, setStory] = useState<Story | null>(null);78  const [chat, setChat] = useState<Chat>({ messages: [] });79  // États principaux du jeu80  const [language, setLanguage] = useState<Language>('fr');81 82  const [round, setRound] = useState<number>(1);83 84  const [requiredWords, setRequiredWords] = useState<string[]>([])85 86  const [currentQuestion, setCurrentQuestion] = useState<string>('');87 88  const [reaction, setReaction] = useState<string>('');89 90 91  const [verdict, setVerdict] = useState<Verdict | null>(null);92  const resetGame = () => {93    setCurrentScene('menu');94    setStory(null);95    setChat({ messages: [] });96    setLanguage('fr');97    setRound(1);98    setRequiredWords([]);99  };100 101  const setNextScene = async () => {102    if (currentScene === 'lawyer') {103      if (round < 4) {104        setCurrentScene('court');105      } else {106        // Generate judge's verdict before ending107        const generateVerdict = async () => {108          try {109            const response = await fetch('/api/text/verdict', {110              method: 'POST',111              headers: {112                'Content-Type': 'application/json',113              },114              body: JSON.stringify({115                language,116                story,117                chat118              })119            });120 121            const data = await response.json();122 123            if (!data.success) {124              throw new Error('Failed to generate verdict');125            }126 127            setVerdict(data.verdict);128          } catch (error) {129            console.error('Error generating verdict:', error);130          }131        };132 133        await generateVerdict();134 135        setCurrentScene('end');136      }137      return;138    }139 140    if (currentScene === 'end') {141      resetGame();142      return;143    }144 145    const currentIndex = sceneOrder.indexOf(currentScene);146    if (currentIndex !== -1 && currentIndex < sceneOrder.length - 1) {147      setCurrentScene(sceneOrder[currentIndex + 1]);148    }149  };150 151  // Props communs à passer aux composants152  const commonProps = {153    intro,154    language,155    setLanguage,156    round,157    setRound,158    setCurrentScene,159    setNextScene,160    story,161    currentQuestion,162    setCurrentQuestion,163    requiredWords,164    setRequiredWords,165    chat,166    setChat,167    reaction,168    setReaction,169    verdict,170    setVerdict171  };172 173  useEffect(() => {174    const fetchStory = async () => {175      try {176        const response = await fetch('/api/text/story', {177          method: 'POST',178          headers: {179            'Content-Type': 'application/json',180          },181          body: JSON.stringify({ language })182        });183 184        const data = await response.json();185 186        if (data.success && data.story) {187          setStory({188            accusation: {189              description: data.story.description,190              alibi: data.story.alibi,191            }192          });193        }194      } catch (error) {195        console.error('Erreur lors de la récupération de l\'histoire:', error);196      }197    };198 199 200    if (currentScene === 'intro') {201      fetchStory();202    }203  // eslint-disable-next-line react-hooks/exhaustive-deps204  }, [currentScene]); // on écoute les changements de currentScene205 206  useEffect(() => {207    const fetchQuestion = async () => {208      try {209        const response = await fetch('/api/text/question', {210          method: 'POST',211          headers: {212            'Content-Type': 'application/json',213          },214          body: JSON.stringify({215            language,216            story: story?.accusation,217            chat: chat218          })219        });220 221        const data = await response.json();222        if (data.question && data.words) {223          setCurrentQuestion(data.question);224          setRequiredWords(data.words);225          if (data.reaction && data.reaction !== '') {226            setReaction(data.reaction);227          }228          setChat(prevChat => ({229            messages: [...prevChat.messages, { content: data.question, role: 'judge' }]230          }));231        }232      } catch (error) {233        console.error('Erreur lors de la récupération de la question:', error);234      }235    };236 237    if ((currentScene === 'accusation' && story) || (currentScene === 'lawyer' && round < 3 && story)) {238      fetchQuestion();239    }240    // eslint-disable-next-line react-hooks/exhaustive-deps241  }, [currentScene]);242 243  switch (currentScene) {244    case 'menu':245      return <MenuScene {...commonProps} />;246    case 'intro':247      return <IntroScene {...commonProps} />;248    case 'accusation':249      return <AccusationScene {...commonProps} />;250    case 'court':251      return <CourtScene {...commonProps} />;252    case 'defense':253      return <DefenseScene {...commonProps} />;254    case 'lawyer':255      return <LawyerScene {...commonProps} />;256    case 'end':257      return <EndScene {...commonProps} />;258    default:259      return <MenuScene {...commonProps} />;260  }261}