Skip to content
Merged
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
Empty file added backend/__init__.py
Empty file.
4 changes: 4 additions & 0 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
annotated-types==0.7.0
anyio==4.8.0
certifi==2025.1.31
click==8.1.8
colorama==0.4.6
fastapi==0.115.8
h11==0.14.0
httpcore==1.0.7
httpx==0.28.1
idna==3.10
iniconfig==2.0.0
packaging==24.2
Expand All @@ -12,6 +15,7 @@ pydantic==2.10.6
pydantic_core==2.27.2
pytest==8.3.4
pytest-asyncio==0.25.3
pytest-mock==3.14.0
sniffio==1.3.1
starlette==0.45.3
typing_extensions==4.12.2
Expand Down
2 changes: 0 additions & 2 deletions backend/tests/test_devices_json.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import pytest
from unittest.mock import patch, mock_open, call
import json
import sys
import os

# Add the parent directory to the sys.path to import devices_json
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import devices_json

Expand Down
29 changes: 29 additions & 0 deletions backend/tests/test_fastAPI.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from fastapi.testclient import TestClient
from backend.fastAPI import app
import pytest

client = TestClient(app)

def test_root():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"message": "Welcome to the Smart Home API!"}

# def test_change_device_name(mocker):
# mocker.patch(
# 'backend.devices_json.changeDeviceName',
# return_value={"error": "Error: Can't use the same name for new_name."},
# autospec=True
# )

# response = client.post("/device/1/name/new_name")
# print(response.json()) # Debugging step to see actual output
# assert response.status_code == 200
# assert response.json() == {"error": "Error: Can't use the same name for new_name."}

# def test_get_updates(mocker):
# mock_updates = ["Changed new_name status to on.", "Error: Can't use the same name for new_name."]
# mocker.patch("backend.devices_json.getUpdates", return_value=mock_updates, autospec=True)
# response = client.get("/updates")
# assert response.status_code == 200
# assert response.json() == {"updates": mock_updates}
7 changes: 0 additions & 7 deletions frontend/src/app/page.js

This file was deleted.

162 changes: 162 additions & 0 deletions frontend/src/app/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
"use client";

import { useState } from "react";
import {
Box,
Button,
TextField,
IconButton,
Typography,
Container,
Paper,
} from "@mui/material";
import LightModeIcon from "@mui/icons-material/LightMode";
import { ThemeProvider, CssBaseline } from "@mui/material";
import getTheme from "./theme";
import Link from "next/link";

const Homepage = () => {
const [isLogin, setIsLogin] = useState(true);
const [darkMode, setDarkMode] = useState(true);

const theme = getTheme(darkMode ? "dark" : "light");

return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Box
sx={{
minHeight: "100vh",
bgcolor: "background.default",
color: "text.primary",
display: "flex",
justifyContent: "center",
alignItems: "center",
position: "relative",
}}
>
{/* Theme Toggle Button (Top Right) */}
<IconButton
sx={{ position: "absolute", top: 16, right: 16 }}
color="inherit"
onClick={() => setDarkMode(!darkMode)}
>
<LightModeIcon sx={{ color: "primary.main", fontSize: "1.5rem" }} />
</IconButton>

{/* Login/Signup Form */}
<Container
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
textAlign: "center",
}}
>
{/* PowerHouse Title */}
<Typography
variant="h4"
sx={{
fontFamily: "JetBrains Mono",
fontWeight: "800",
mb: 2,
color: "primary.main",
fontSize: "3rem",
}}
>
PowerHouse
</Typography>

<Paper
elevation={6}
sx={{
p: 4,
width: "100%",
maxWidth: 400,
bgcolor: "background.paper",
}}
>
{/* Toggle Buttons */}
<Box sx={{ display: "flex", mb: 3 }}>
<Button
fullWidth
variant={isLogin ? "contained" : "outlined"}
color="primary"
onClick={() => setIsLogin(true)}
sx={{
fontFamily: "JetBrains Mono",
fontWeight: 800,
color: isLogin ? "white" : theme.palette.primary.main,
borderColor: theme.palette.primary.main,
}}
>
Login
</Button>
<Button
fullWidth
variant={!isLogin ? "contained" : "outlined"}
color="primary"
onClick={() => setIsLogin(false)}
sx={{
fontFamily: "JetBrains Mono",
fontWeight: 800,
color: !isLogin ? "white" : theme.palette.primary.main,
borderColor: theme.palette.primary.main,
}}
>
Sign Up
</Button>
</Box>

{/* Form Fields */}
<Link href="/dashboard">
<Box
component="form"
sx={{ display: "flex", flexDirection: "column", gap: 2 }}
>
{!isLogin && (
<TextField
label="Username"
variant="outlined"
fullWidth
required
sx={{ fontFamily: "JetBrains Mono" }}
/>
)}
<TextField
label="Email"
type="email"
variant="outlined"
fullWidth
required
/>
<TextField
label="Password"
type="password"
variant="outlined"
fullWidth
required
/>
<Button
type="submit"
variant="contained"
color="primary"
fullWidth
sx={{
fontFamily: "JetBrains Mono",
fontWeight: 800,
color: "white",
}}
>
{isLogin ? "Login" : "Sign Up"}
</Button>
</Box>
</Link>
</Paper>
</Container>
</Box>
</ThemeProvider>
);
};

export default Homepage;