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
33 changes: 31 additions & 2 deletions frontend/src/lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,44 @@ async function request(endpoint, token, options = {}) {
}

export function createProject(token, { name, city_input }) {
if (!name.trim() || !city_input.trim()) {
console.error("Field cannot be empty")
return
}
return request("/projects", token, {
method: "POST",
body: JSON.stringify({ name, city_input })
})
}

export function updateProject(token, projectId, updates) {
return request(`/projects/${projectId}`, token, {
export function updateResource(token, endpoint, updates) {
if (!updates || typeof updates !== "object" || Object.keys(updates).length === 0) {
console.error("No updates provided")
return
}

return request(endpoint, token, {
method: "PATCH",
body: JSON.stringify(updates)
})
}

export function updateResourceField(token, endpoint, field, value, options = {}) {
const { trim = false, normalize = (currentValue) => currentValue } = options

if (value === null || value === undefined) {
return
}

let normalizedValue = normalize(value)

if (trim && typeof normalizedValue === "string") {
normalizedValue = normalizedValue.trim()
}

return updateResource(token, endpoint, { [field]: normalizedValue })
}

export function updateProject(token, projectId, updates) {
return updateResource(token, `/projects/${projectId}`, updates)
}
39 changes: 19 additions & 20 deletions frontend/src/screens/CreateScenario.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,19 @@ export default function CreateScenario() {
const { token } = useContext(AuthContext)
const { data: project, loading: loading, error: error } = useApi(`/api/projects/${projectId}`)

const [scenarioName, setScenarioName] = useState("Scenario Name")

async function handleNameSubmit(e) {
e?.preventDefault?.()

try {
await updateResourceField(token, `/projects/${projectId}/scenarios/${scenarioId}`, "name", scenarioName, { trim: true })
} catch (error) {
console.error("Error updating scenario name:", error)
}
console.log("Scenario name updated:", scenarioName)
}

if (loading) return <p>Loading...</p>
if (error) return <p>Something went wrong.</p>

Expand All @@ -62,9 +75,9 @@ export default function CreateScenario() {
</Breadcrumb>
<div className="flex justify-between items-center">
<form>
<input id="projectName"
value="Scenario Name"
// onChange={(e) => setProjectName(e.target.value)}
<input id="scenarioName"
value={scenarioName}
onChange={(e) => setScenarioName(e.target.value)}
/>
</form>
<Link key={project.id} to={`/projects/${project.id}`}>
Expand All @@ -76,17 +89,9 @@ export default function CreateScenario() {
<div className="flex gap-4">
<FieldGroup>
<h3>System configuration</h3>
{/* <form>
<label htmlFor="amount">Module amount</label>
<input id="amount"
value="aAaaa"
// onChange={(e) => setProjectLocation(e.target.value)}
/>
</form> */}

<Field>
<FieldLabel htmlFor="amount">Module amount</FieldLabel>
<Input id="amount" type="number" placeholder="e.g. 30" />
<Input id="amount" type="number" placeholder="e.g. 100" />
<FieldDescription>
Quantity of modules in the system
</FieldDescription>
Expand All @@ -99,10 +104,10 @@ export default function CreateScenario() {
</FieldDescription>
</Field>
<Field>
<FieldLabel htmlFor="orientation">Orientation</FieldLabel>
<FieldLabel htmlFor="orientation">Azimuth</FieldLabel>
<Input id="orientation" type="number" placeholder="e.g. 0" min="0" max="360"/>
<FieldDescription>
The angle relative to the South, in degrees. South orientation is 0°
Orientation relative to the South, in degrees. South orientation is 0°
</FieldDescription>
</Field>
</FieldGroup>
Expand All @@ -125,12 +130,6 @@ export default function CreateScenario() {
</Field>
<Table>
<TableCaption>Selected solar module</TableCaption>
{/* <TableHeader>
<TableRow>
<TableHead className="text-right">Technology</TableHead>
<TableHead className="text-left">Nominal power</TableHead>
</TableRow>
</TableHeader> */}
<TableBody>
<TableRow key="0">
<TableCell className="font-semibold">Technology</TableCell>
Expand Down
51 changes: 12 additions & 39 deletions frontend/src/screens/Project.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,23 @@ import Header from "../components/Header";
import ScenarioCard from "../components/ScenarioCard";

import { AuthContext } from "../lib/AuthContext"
import { useApi } from "../lib/api"
import { useApi, updateResourceField } from "../lib/api"


const Project = () => {
const { projectId, scenarioId } = useParams();
const { token } = useContext(AuthContext)
const { data: project, loading: projLoading, error: projError } = useApi(`/api/projects/${params.projectId}`)
const { data: scenarios, loading: scenLoading, error: scenError } = useApi(`/api/projects/${params.projectId}/scenarios`)
const { data: project, loading: projLoading, error: projError } = useApi(`/api/projects/${projectId}`)
const { data: scenarios, loading: scenLoading, error: scenError } = useApi(`/api/projects/${projectId}/scenarios`)

const [projectName, setProjectName] = useState("")
const [projectLocation, setProjectLocation] = useState("")

useEffect(() => {
if (project) setProjectName(project.name)
if (project) {
setProjectName(project.name ?? "")
setProjectLocation(project.location ?? "")
}
}, [project])

useEffect(() => {
Expand All @@ -40,53 +43,23 @@ const Project = () => {
async function handleNameSubmit(e) {
e.preventDefault()

if (!projectName.trim()) {
console.error("Project name cannot be empty")
return
}

try {
const response = await fetch(`/api/projects/${params.projectId}`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`
},
body: JSON.stringify({ name: projectName.trim() })
})

if (!response.ok) {
console.error("Failed to update project name")
}
await updateResourceField(token, `/projects/${projectId}`, "name", projectName, { trim: true })
} catch (error) {
console.error("Error updating project name:", error)
}
console.log("Project name updated:", projectName)
}

async function handleLocationSubmit(e) {
async function handleLocationSubmit(e) {
e.preventDefault()

if (!projectLocation.trim()) {
console.error("Project location cannot be empty")
return
}

try {
const response = await fetch(`/api/projects/${params.projectId}`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`
},
body: JSON.stringify({ location: projectLocation.trim() })
})

if (!response.ok) {
console.error("Failed to update project location")
}
await updateResourceField(token, `/projects/${projectId}`, "location", projectLocation, { trim: true })
} catch (error) {
console.error("Error updating project location:", error)
}
console.log("Location updated:", projectLocation)
}

return (
Expand Down
Loading