Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions Team414/crime-simulator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# env files (can opt-in for committing if needed)
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
5 changes: 5 additions & 0 deletions Team414/crime-simulator/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<!-- BEGIN:nextjs-agent-rules -->
# This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
<!-- END:nextjs-agent-rules -->
1 change: 1 addition & 0 deletions Team414/crime-simulator/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
21 changes: 21 additions & 0 deletions Team414/crime-simulator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Crime Investigation Simulator

## 👩‍💻 Team Name
Team 414

## 🚀 Project Overview
An interactive crime investigation simulator where users analyze evidence and identify the suspect based on suspicion scoring.

## ⚙️ Features
- Evidence selection system
- Dynamic suspicion score updates
- Interactive UI
- Final accusation system

## 🛠 Tech Stack
- Next.js
- React
- Tailwind CSS

## 🎥 Demo Video
<video controls src="Screen Recording 2026-04-04 171000.mp4" title="Title"></video>
Binary file not shown.
Binary file added Team414/crime-simulator/app/favicon.ico
Binary file not shown.
26 changes: 26 additions & 0 deletions Team414/crime-simulator/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@import "tailwindcss";

:root {
--background: #ffffff;
--foreground: #171717;
}

@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}

@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
}

body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}
33 changes: 33 additions & 0 deletions Team414/crime-simulator/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";

const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});

const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});

export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html
lang="en"
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
>
<body className="min-h-full flex flex-col">{children}</body>
</html>
);
}
139 changes: 139 additions & 0 deletions Team414/crime-simulator/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
"use client";
import { useState } from "react";

export default function Home() {
const [suspects, setSuspects] = useState([
{ id: 1, name: "Rahul", role: "Friend", suspicion: 20 },
{ id: 2, name: "Amit", role: "Coworker", suspicion: 30 },
]);

const [selectedEvidence, setSelectedEvidence] = useState<any>(null);
const [result, setResult] = useState<string | null>(null);

const evidence = [
{ id: 1, name: "📱 Phone Log", impact: 20 },
{ id: 2, name: "🧾 Fake Alibi", impact: 30 },
];

const applyEvidence = (id: number) => {
if (!selectedEvidence) return;

setSuspects((prev: any[]) =>
prev.map((s: any) =>
s.id === id
? {
...s,
suspicion: Math.min(
s.suspicion + selectedEvidence.impact,
100
),
}
: s
)
);
};

const accuse = () => {
const max = suspects.reduce((a: any, b: any) =>
a.suspicion > b.suspicion ? a : b
);

setResult(
max.id === 2
? "✅ Correct! Amit is guilty"
: "❌ Wrong suspect"
);
};

return (
<div className="min-h-screen bg-gray-900 text-white px-4 py-6 sm:px-6 lg:px-8">

{/* CONTAINER */}
<div className="max-w-5xl mx-auto">

{/* HEADER */}
<div className="bg-gray-800 p-4 sm:p-6 rounded-xl mb-6 text-center sm:text-left">
<h1 className="text-xl sm:text-2xl font-bold">
🕵️ Crime Investigation
</h1>
<p className="text-yellow-400 text-sm sm:text-base">
🟡 Investigating
</p>
</div>

{/* EVIDENCE */}
<h2 className="mb-2 text-sm sm:text-base">🔍 Evidence</h2>

<div className="grid grid-cols-2 sm:flex gap-3 sm:gap-4 mb-6">
{evidence.map((e) => (
<div
key={e.id}
onClick={() => setSelectedEvidence(e)}
className={`p-3 sm:p-4 text-sm sm:text-base text-center rounded-xl cursor-pointer transition ${
selectedEvidence?.id === e.id
? "bg-yellow-400 text-black"
: "bg-gray-800 hover:bg-gray-700"
}`}
>
{e.name}
</div>
))}
</div>

{/* SUSPECTS */}
<h2 className="mb-2 text-sm sm:text-base">👤 Suspects</h2>

<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
{suspects.map((s) => (
<div
key={s.id}
onClick={() => applyEvidence(s.id)}
className="bg-gray-800 p-4 sm:p-5 rounded-xl cursor-pointer hover:bg-gray-700 transition"
>
<h3 className="text-base sm:text-lg font-semibold">
{s.name}
</h3>
<p className="text-gray-400 text-sm">{s.role}</p>

{/* Progress */}
<div className="mt-2">
<div className="w-full bg-gray-700 h-2 rounded">
<div
className="bg-red-500 h-2 rounded transition-all"
style={{ width: `${s.suspicion}%` }}
></div>
</div>
<p className="text-xs sm:text-sm mt-1">
🔥 {s.suspicion}%
</p>
</div>

{s.suspicion > 70 && (
<p className="text-red-400 text-xs sm:text-sm mt-1">
⚠️ Highly Suspicious
</p>
)}
</div>
))}
</div>

{/* BUTTON */}
<div className="mt-6 text-center">
<button
onClick={accuse}
className="w-full sm:w-auto bg-red-600 px-6 py-3 rounded-xl hover:bg-red-700 transition"
>
🎯 Accuse Suspect
</button>

{result && (
<p className="mt-4 text-base sm:text-lg font-semibold">
{result}
</p>
)}
</div>

</div>
</div>
);
}
14 changes: 14 additions & 0 deletions Team414/crime-simulator/components/AccuseButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default function AccuseButton({ accuse, result }: any) {
return (
<div className="mt-8 text-center">
<button
onClick={accuse}
className="bg-red-600 px-6 py-3 rounded-xl"
>
🎯 Accuse Suspect
</button>

{result && <p className="mt-4 text-lg">{result}</p>}
</div>
);
}
9 changes: 9 additions & 0 deletions Team414/crime-simulator/components/CaseHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default function CaseHeader() {
return (
<div className="bg-gray-800 p-5 rounded-xl mb-6">
<h1 className="text-2xl font-bold">🕵️ Crime Investigation</h1>
<p className="text-gray-400">Bank Robbery Case</p>
<p className="text-yellow-400">🟡 Investigating</p>
</div>
);
}
23 changes: 23 additions & 0 deletions Team414/crime-simulator/components/EvidencePanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export default function EvidencePanel({
evidence,
selected,
setSelected,
}: any) {
return (
<div className="flex gap-4">
{evidence.map((e: any) => (
<div
key={e.id}
onClick={() => setSelected(e)}
className={`p-3 rounded-xl cursor-pointer ${
selected?.id === e.id
? "bg-yellow-400 text-black"
: "bg-gray-800 hover:bg-gray-700"
}`}
>
{e.name}
</div>
))}
</div>
);
}
14 changes: 14 additions & 0 deletions Team414/crime-simulator/components/Insights.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default function Insights({ suspects }: any) {
const high = suspects.find((s: any) => s.suspicion > 60);

return (
<div className="bg-gray-800 p-4 rounded-xl mt-6">
<h2 className="font-bold mb-2">🧠 Insights</h2>
{high ? (
<p>{high.name} seems suspicious due to strong evidence.</p>
) : (
<p>No strong leads yet.</p>
)}
</div>
);
}
21 changes: 21 additions & 0 deletions Team414/crime-simulator/components/SuspectCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Card from "./ui/Card";
import ProgressBar from "./ui/ProgressBar";

export default function SuspectCard({ suspect, onClick }: any) {
return (
<Card>
<div onClick={onClick} className="cursor-pointer">
<h2 className="text-xl font-bold">{suspect.name}</h2>
<p className="text-gray-400">{suspect.role}</p>

<ProgressBar value={suspect.suspicion} />

<p className="text-sm mt-2">🔥 {suspect.suspicion}%</p>

{suspect.suspicion > 70 && (
<p className="text-red-400">⚠️ Highly Suspicious</p>
)}
</div>
</Card>
);
}
7 changes: 7 additions & 0 deletions Team414/crime-simulator/components/ui/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function Card({ children }: any) {
return (
<div className="bg-gray-800 p-5 rounded-xl shadow-lg">
{children}
</div>
);
}
10 changes: 10 additions & 0 deletions Team414/crime-simulator/components/ui/ProgressBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default function ProgressBar({ value }: { value: number }) {
return (
<div className="w-full bg-gray-700 h-2 rounded mt-2">
<div
className="bg-red-500 h-2 rounded"
style={{ width: `${value}%` }}
></div>
</div>
);
}
9 changes: 9 additions & 0 deletions Team414/crime-simulator/data/mockData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const suspects = [
{ id: 1, name: "Rahul", role: "Friend", suspicion: 20 },
{ id: 2, name: "Amit", role: "Coworker", suspicion: 30 },
];

export const evidence = [
{ id: 1, name: "📱 Phone Log", impact: 20 },
{ id: 2, name: "🧾 Fake Alibi", impact: 30 },
];
Loading