Great — below are TypeScript + MUI v5 components split into separate files, using the sx prop and including sample data + placeholder images. Copy these into your src/ folder (adjust paths as needed).
- src/components/NavBar.tsx
import React from "react";
import AppBar from "@mui/material/AppBar";
import Toolbar from "@mui/material/Toolbar";
import IconButton from "@mui/material/IconButton";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import Box from "@mui/material/Box";
import MenuIcon from "@mui/icons-material/Menu";
const NavBar: React.FC = () => {
return (
<AppBar position="sticky" color="inherit" elevation={2}>
<Toolbar sx={{ display: "flex", justifyContent: "space-between" }}>
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
<IconButton edge="start" color="
rimary"><MenuIcon /></IconButton>
<Typography variant="h6" color="
rimary" sx={{ fontWeight: 700 }}>
AutoShop
</Typography>
</Box>
<Box sx={{ display: "flex", gap: 2, alignItems: "center" }}>
<Button color="inherit">Inventory</Button>
<Button color="inherit">Services</Button>
<Button color="inherit">Contact</Button>
<Button variant="contained" color="
rimary">Sell Trade-in</Button>
</Box>
</Toolbar>
</AppBar>
);
};
export default NavBar;
- src/components/Hero.tsx
import React from "react";
import Box from "@mui/material/Box";
import Container from "@mui/material/Container";
import Typography from "@mui/material/Typography";
import TextField from "@mui/material/TextField";
import Button from "@mui/material/Button";
import InputAdornment from "@mui/material/InputAdornment";
import SearchIcon from "@mui/icons-material/Search";
const Hero: React.FC<{ onSearch?: (q: string) => void }> = ({ onSearch }) => {
const [q, setQ] = React.useState(""
;
return (
<Box
sx={{
backgroundImage: `url("<a href="https://images.unsplash.com/photo-1511919884226-fd3cad34687c?auto=format&fit=crop&w=1400&q=60"" target="_blank">https://images.unsplash.com/photo-1511919884226-fd3cad34687c?auto=format&fit=crop&w=1400&q=60"</a>
`,
backgroundSize: "cover",
backgroundPosition: "center",
py: { xs: 6, md: 12 },
color: "common.white",
}}
>
<Container>
<Typography variant="h3" sx={{ fontWeight: 800, mb: 2 }}>
Find Your Next Ride
</Typography>
<Typography variant="h6" sx={{ mb: 4, opacity: 0.9 }}>
Top-quality used cars, financing & trade-ins — hassle free.
</Typography>
<Box sx={{ display: "flex", gap: 2, maxWidth: 800 }}>
<TextField
value={q}
onChange={(e) => setQ(e.target.value)}
placeholder="Search make, model or year"
fullWidth
size="large"
variant="filled"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
sx={{ bgcolor: "rgba(255,255,255,0.9)", borderRadius: 1 }}
/>
<Button
variant="contained"
color="
rimary"
onClick={() => onSearch?.(q)}
sx={{ px: 4 }}
>
Search
</Button>
</Box>
</Container>
</Box>
);
};
export default Hero;
- src/components/Services.tsx
import React from "react";
import Container from "@mui/material/Container";
import Grid from "@mui/material/Grid";
import Paper from "@mui/material/Paper";
import Typography from "@mui/material/Typography";
import LocalAtmIcon from "@mui/icons-material/LocalAtm";
import DirectionsCarIcon from "@mui/icons-material/DirectionsCar";
import VerifiedUserIcon from "@mui/icons-material/VerifiedUser";
const services = [
{ title: "Financing", desc: "Flexible plans & approvals", icon: <LocalAtmIcon /> },
{ title: "Test Drives", desc: "Book a test drive today", icon: <DirectionsCarIcon /> },
{ title: "Warranty", desc: "Optional extended protection", icon: <VerifiedUserIcon /> },
];
const Services: React.FC = () => (
<Container sx={{ py: 6 }}>
<Typography variant="h4" sx={{ mb: 3, fontWeight: 700 }}>
Our Services
</Typography>
<Grid container spacing={2}>
{services.map((s) => (
<Grid item xs={12} md={4} key={s.title}>
<
aper sx={{ p: 3, display: "flex", gap: 2, alignItems: "center" }}>
<Box sx={{ fontSize: 36, color: "
rimary.main" }}>{s.icon}</Box>
<div>
<Typography variant="h6">{s.title}</Typography>
<Typography variant="body2" color="text.secondary">{s.desc}</Typography>
</div>
</Paper>
</Grid>
))}
</Grid>
</Container>
);
export default Services;
import { Box } from "@mui/material";
(Note: The small helper import Box is at file bottom for clarity.)
- src/types/car.ts
export interface Car {
id: string;
make: string;
model: string;
year: number;
price: number; // in USD
mileage: number;
image: string;
color?: string;
transmission?: "Auto" | "Manual";
}
- src/data/sampleCars.ts
import { Car } from "../types/car";
export const sampleCars: Car[] = [
{
id: "1",
make: "Toyota",
model: "Camry",
year: 2019,
price: 18999,
mileage: 42000,
image: "<a href="https://source.unsplash.com/collection/190727/800x600?car"" target="_blank">https://source.unsplash.com/collection/190727/800x600?car"</a>;,
color: "White",
transmission: "Auto",
},
{
id: "2",
make: "Honda",
model: "Civic",
year: 2018,
price: 14950,
mileage: 55000,
image: "<a href="https://source.unsplash.com/collection/190727/800x600?sedan"" target="_blank">https://source.unsplash.com/collection/190727/800x600?sedan"</a>;,
color: "Blue",
transmission: "Auto",
},
{
id: "3",
make: "Ford",
model: "F-150",
year: 2020,
price: 27999,
mileage: 30000,
image: "<a href="https://source.unsplash.com/collection/190727/800x600?truck"" target="_blank">https://source.unsplash.com/collection/190727/800x600?truck"</a>;,
color: "Red",
transmission: "Auto",
},
];
- src/components/CarCard.tsx
import React from "react";
import Card from "@mui/material/Card";
import CardMedia from "@mui/material/CardMedia";
import CardContent from "@mui/material/CardContent";
import Typography from "@mui/material/Typography";
import CardActions from "@mui/material/CardActions";
import Button from "@mui/material/Button";
import Grid from "@mui/material/Grid";
import { Car } from "../types/car";
const CarCard: React.FC<{ car: Car }> = ({ car }) => {
return (
<Card sx={{ height: "100%", display: "flex", flexDirection: "column" }}>
<CardMedia
component="img"
height="180"
image={car.image}
alt={`${car.make} ${car.model}`}
/>
<CardContent sx={{ flexGrow: 1 }}>
<Typography variant="h6" sx={{ fontWeight: 700 }}>
{car.year} {car.make} {car.model}
</Typography>
<Typography variant="body2" color="text.secondary">
{car.mileage.toLocaleString()} miles • {car.transmission}
</Typography>
<Typography variant="h6" sx={{ mt: 1, color: "
rimary.main" }}>
${car.price.toLocaleString()}
</Typography>
</CardContent>
<CardActions>
<Button size="small">View</Button>
<Button size="small" variant="contained">Contact</Button>
</CardActions>
</Card>
);
};
export default CarCard;
- src/components/InventoryGrid.tsx
import React from "react";
import Container from "@mui/material/Container";
import Grid from "@mui/material/Grid";
import Typography from "@mui/material/Typography";
import CarCard from "./CarCard";
import { Car } from "../types/car";
const InventoryGrid: React.FC<{ cars: Car[] }> = ({ cars }) => {
return (
<Container sx={{ py: 6 }}>
<Typography variant="h4" sx={{ mb: 3, fontWeight: 700 }}>
Inventory
</Typography>
<Grid container spacing={3}>
{cars.map((c) => (
<Grid item xs={12} sm={6} md={4} key={<a href="http://c.id" target="_blank">c.id</a>}>
<CarCard car={c} />
</Grid>
))}
</Grid>
</Container>
);
};
export default InventoryGrid;
- src/components/Testimonials.tsx
import React from "react";
import Container from "@mui/material/Container";
import Paper from "@mui/material/Paper";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import Avatar from "@mui/material/Avatar";
import Box from "@mui/material/Box";
const items = [
{ name: "Samantha", text: "Great experience — smooth trade-in!", avatar: "" },
{ name: "Marcus", text: "Awesome price and friendly staff.", avatar: "" },
{ name: "Leah", text: "Financing was easy and quick.", avatar: "" },
];
const Testimonials: React.FC = () => {
const [i, setI] = React.useState(0);
return (
<Container sx={{ py: 6 }}>
<Typography variant="h5" sx={{ mb: 2, fontWeight: 700 }}>What customers say</Typography>
<
aper sx={{ p: 3, display: "flex", alignItems: "center", gap: 3 }}>
<Avatar sx={{ width: 64, height: 64 }}>{items[i].name.charAt(0)}</Avatar>
<Box sx={{ flex: 1 }}>
<Typography variant="subtitle1" sx={{ fontWeight: 700 }}>{items[i].name}</Typography>
<Typography variant="body2" color="text.secondary">{items[i].text}</Typography>
</Box>
<Box sx={{ display: "flex", gap: 1 }}>
<Button onClick={() => setI((p) => (p - 1 + items.length) % items.length)}>
rev</Button>
<Button onClick={() => setI((p) => (p + 1) % items.length)}>Next</Button>
</Box>
</Paper>
</Container>
);
};
export default Testimonials;
- src/components/CTABar.tsx
import React from "react";
import Paper from "@mui/material/Paper";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import Container from "@mui/material/Container";
const CTABar: React.FC = () => (
<
aper sx={{ bgcolor: "
rimary.main", color: "common.white", py: 4 }}>
<Container sx={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
<div>
<Typography variant="h6" sx={{ fontWeight: 700 }}>Ready to sell your car?</Typography>
<Typography variant="body2">Get an instant appraisal & trade-in offer today.</Typography>
</div>
<Button variant="contained" color="secondary">Get Appraisal</Button>
</Container>
</Paper>
);
export default CTABar;
- src/components/ContactForm.tsx
import React from "react";
import Container from "@mui/material/Container";
import TextField from "@mui/material/TextField";
import Button from "@mui/material/Button";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
const ContactForm: React.FC = () => {
const [form, setForm] = React.useState({ name: "", email: "", message: "" });
return (
<Container sx={{ py: 6 }}>
<Typography variant="h5" sx={{ mb: 2, fontWeight: 700 }}>Contact Us</Typography>
<Box component="form" sx={{ display: "grid", gap: 2, maxWidth: 600 }}>
<TextField label="Name" value={<a href="http://form.name" target="_blank">form.name</a>} onChange={(e) => setForm({ ...form, name: e.target.value })} />
<TextField label="Email" value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} />
<TextField label="Message" multiline rows={4} value={form.message} onChange={(e) => setForm({ ...form, message: e.target.value })} />
<Button variant="contained">Send Message</Button>
</Box>
</Container>
);
};
export default ContactForm;
- src/components/Footer.tsx
import React from "react";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
const Footer: React.FC = () => (
<Box sx={{ bgcolor: "grey.100", py: 4, mt: 6 }}>
<Box sx={{ maxWidth: 1100, mx: "auto", px: 2 }}>
<Typography variant="subtitle1" sx={{ fontWeight: 700 }}>AutoShop</Typography>
<Typography variant="body2" color="text.secondary">© {new Date().getFullYear()} AutoShop — All rights reserved.</Typography>
</Box>
</Box>
);
export default Footer;
- src/App.tsx
import React from "react";
import CssBaseline from "@mui/material/CssBaseline";
import NavBar from "./components/NavBar";
import Hero from "./components/Hero";
import Services from "./components/Services";
import InventoryGrid from "./components/InventoryGrid";
import Testimonials from "./components/Testimonials";
import CTABar from "./components/CTABar";
import ContactForm from "./components/ContactForm";
import Footer from "./components/Footer";
import { sampleCars } from "./data/sampleCars";
const App: React.FC = () => {
const handleSearch = (q?: string) => {
// For demo, just log — integrate with filtering / state as needed
console.log("Search:", q);
};
return (
<>
<CssBaseline />
<NavBar />
<Hero onSearch={handleSearch} />
<Services />
<InventoryGrid cars={sampleCars} />
<Testimonials />
<CTABar />
<ContactForm />
<Footer />
</>
);
};
export default App;
- src/index.tsx
import React from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
const root = createRoot(document.getElementById("root"
!);
root.render(<App />
;
Notes and tips:
- These use MUI v5 and the sx prop only (no custom theme required). Install @mui/material, @emotion/react, @emotion/styled and @mui/icons-material.
- Replace placeholder Unsplash URLs with your own images or static assets for consistent results.
- Hook up real filtering, routing (react-router) or state management (zustand/redux) as your app needs.
- If you want all files combined into one single file for a quick demo, tell me and I’ll merge them.
Want the same but with a custom theme or Tailwind instead?