as an expert reacty/typescript expert fix this game so it works correctly as a platformer:

import React, { useState, useEffect, useRef } from "react";

// Constants
const GRAVITY = 980; // Pixels per second squared
const JUMP_STRENGTH = -600; // Pixels per second
const MOVE_SPEED = 500; // Pixels per second
const PLAYER_WIDTH = 50;
const PLAYER_HEIGHT = 50;
const PLATFORM_WIDTH = 300;
const PLATFORM_HEIGHT = 120;
const VIEW_WIDTH = 800;
const VIEW_HEIGHT = 600;

// Platform component
const Platform = ({ width, height, top, left }) => (
    <div
        style={{
            position: "absolute",
            width: `${width}px`,
            height: `${height}px`,
            backgroundColor: "brown",
            left: `${left}px`,
            top: `${top}px`,
        }}
    />
);

// Player component
const Player = ({ x, y }) => (
    <div
        style={{
            position: "absolute",
            width: `${PLAYER_WIDTH}px`,
            height: `${PLAYER_HEIGHT}px`,
            backgroundColor: "blue",
            left: `${x - PLAYER_WIDTH / 2}px`,
            top: `${y}px`,
            zIndex: 2,
        }}
    />
);

function GameMain() {
    const [playerPosition, setPlayerPosition] = useState({
        x: VIEW_WIDTH / 2,
        y: VIEW_HEIGHT - PLATFORM_HEIGHT - PLAYER_HEIGHT,
    });
    const [playerVelocity, setPlayerVelocity] = useState({ x: 0, y: 0 });
    const [isGrounded, setIsGrounded] = useState(true);
    const [platforms, setPlatforms] = useState([
        {
            width: VIEW_WIDTH,
            height: PLATFORM_HEIGHT,
            top: VIEW_HEIGHT - PLATFORM_HEIGHT,
            left: 0,
        },
    ]);

    const lastTimeRef = useRef(performance.now());
    const keysPressed = useRef({ left: false, right: false, jump: false });

    const createNewPlatform = () => ({
        width: PLATFORM_WIDTH,
        height: PLATFORM_HEIGHT,
        top: Math.max(PLATFORM_HEIGHT, Math.random() * (VIEW_HEIGHT - PLATFORM_HEIGHT - 10)),
        left: platforms[platforms.length - 1].left + PLATFORM_WIDTH + Math.random() * 400 + 200,
    });

    // Check collision between player and platforms
    const checkCollisionWithPlatforms = () => {
        const playerRect = {
            left: playerPosition.x - PLAYER_WIDTH / 2,
            top: playerPosition.y,
            right: playerPosition.x + PLAYER_WIDTH / 2,
            bottom: playerPosition.y + PLAYER_HEIGHT,
        };

        for (const platform of platforms) {
            const platformRect = {
                left: platform.left,
                top: platform.top,
                right: platform.left + platform.width,
                bottom: platform.top + platform.height,
            };
            if (
                playerRect.right > platformRect.left &&
                playerRect.left < platformRect.right &&
                playerRect.bottom > platformRect.top &&
                playerRect.top < platformRect.bottom
            ) {
                return platform; // Colliding with platform
            }
        }
        return null;
    };

    // Game loop
    const gameLoop = () => {
        const now = performance.now();
        const deltaTime = (now - lastTimeRef.current) / 1000.0;
        lastTimeRef.current = now;

        // Update player velocity and position
        const newVelocity = { ...playerVelocity };
        let newPositionX = playerPosition.x;
        if (keysPressed.current.left) {
            newPositionX -= MOVE_SPEED * deltaTime;
        }
        if (keysPressed.current.right) {
            newPositionX += MOVE_SPEED * deltaTime;
        }
        let newPositionY = playerPosition.y;
        if (!isGrounded) {
            newVelocity.y += GRAVITY * deltaTime; // Apply gravity
        } else {
            newVelocity.y = 0;
        }
        if (keysPressed.current.jump && isGrounded) {
            newVelocity.y = JUMP_STRENGTH; // Apply jump
            setIsGrounded(false);
            keysPressed.current.jump = false;
        }
        newPositionY = Math.max(0, newPositionY + newVelocity.y * deltaTime);

        // Check for collisions
        const collided = checkCollisionWithPlatforms();
        // Collision response
        if (collided) {
            setIsGrounded(true);
            newPositionY = collided.top - PLAYER_HEIGHT;
        } else {
            setIsGrounded(false);
        }

        setPlayerPosition({ x: newPositionX, y: newPositionY });
        setPlayerVelocity(newVelocity);

        // Create new platform if needed
        if (platforms[platforms.length - 1].left < playerPosition.x + VIEW_WIDTH) {
            setPlatforms((prevPlatforms) => [...prevPlatforms, createNewPlatform()]);
        }

        // Remove platforms that are offscreen
        setPlatforms((prevPlatforms) => prevPlatforms.filter((platform) => platform.left > playerPosition.x - VIEW_WIDTH));

        requestAnimationFrame(gameLoop);
    };

    useEffect(() => {
        const handleKeyDown = ({ key }) => {
            if (key === "ArrowLeft") keysPressed.current.left = true;
            if (key === "ArrowRight") keysPressed.current.right = true;
            if (key === "ArrowUp" || key === " ") keysPressed.current.jump = true;
        };

        const handleKeyUp = ({ key }) => {
            if (key === "ArrowLeft") keysPressed.current.left = false;
            if (key === "ArrowRight") keysPressed.current.right = false;
            if (key === "ArrowUp" || key === " ") keysPressed.current.jump = false; // Added "Space" for jump
        };

        window.addEventListener("keydown", handleKeyDown);
        window.addEventListener("keyup", handleKeyUp);
        requestAnimationFrame(gameLoop);

        return () => {
            window.removeEventListener("keydown", handleKeyDown);
            window.removeEventListener("keyup", handleKeyUp);
        };
    }, []);

    return (
        <div
            style={{
                position: "relative",
                width: `${VIEW_WIDTH}px`,
                height: `${VIEW_HEIGHT}px`,
                overflow: "hidden",
                backgroundColor: "lightblue",
            }}
        >
            <Player x={playerPosition.x + VIEW_WIDTH / 2} y={playerPosition.y} />
            {platforms.map((platform, index) => (
                <Platform
                    key={index}
                    {...platform}
                    left={platform.left - playerPosition.x + VIEW_WIDTH / 2}
                />
            ))}
        </div>
    );
}

export default GameMain;