🔍
37 |
36 |
37 | *Address search feature*
38 |
39 |
40 |
41 | *Summary section*
42 |
43 |
44 |
--------------------------------------------------------------------------------
/styles/Home.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | padding: 0 2rem;
3 | }
4 |
5 | .main {
6 | min-height: 100vh;
7 | padding: 4rem 0;
8 | flex: 1;
9 | display: flex;
10 | flex-direction: column;
11 | justify-content: center;
12 | align-items: center;
13 | }
14 |
15 | .footer {
16 | display: flex;
17 | flex: 1;
18 | padding: 2rem 0;
19 | border-top: 1px solid #eaeaea;
20 | justify-content: center;
21 | align-items: center;
22 | }
23 |
24 | .footer a {
25 | display: flex;
26 | justify-content: center;
27 | align-items: center;
28 | flex-grow: 1;
29 | }
30 |
31 | .title a {
32 | color: #0070f3;
33 | text-decoration: none;
34 | }
35 |
36 | .title a:hover,
37 | .title a:focus,
38 | .title a:active {
39 | text-decoration: underline;
40 | }
41 |
42 | .title {
43 | margin: 0;
44 | line-height: 1.15;
45 | font-size: 4rem;
46 | }
47 |
48 | .title,
49 | .description {
50 | text-align: center;
51 | }
52 |
53 | .description {
54 | margin: 4rem 0;
55 | line-height: 1.5;
56 | font-size: 1.5rem;
57 | }
58 |
59 | .code {
60 | background: #fafafa;
61 | border-radius: 5px;
62 | padding: 0.75rem;
63 | font-size: 1.1rem;
64 | font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
65 | Bitstream Vera Sans Mono, Courier New, monospace;
66 | }
67 |
68 | .grid {
69 | display: flex;
70 | align-items: center;
71 | justify-content: center;
72 | flex-wrap: wrap;
73 | max-width: 800px;
74 | }
75 |
76 | .card {
77 | margin: 1rem;
78 | padding: 1.5rem;
79 | text-align: left;
80 | color: inherit;
81 | text-decoration: none;
82 | border: 1px solid #eaeaea;
83 | border-radius: 10px;
84 | transition: color 0.15s ease, border-color 0.15s ease;
85 | max-width: 300px;
86 | }
87 |
88 | .card:hover,
89 | .card:focus,
90 | .card:active {
91 | color: #0070f3;
92 | border-color: #0070f3;
93 | }
94 |
95 | .card h2 {
96 | margin: 0 0 1rem 0;
97 | font-size: 1.5rem;
98 | }
99 |
100 | .card p {
101 | margin: 0;
102 | font-size: 1.25rem;
103 | line-height: 1.5;
104 | }
105 |
106 | .logo {
107 | height: 1em;
108 | margin-left: 0.5rem;
109 | }
110 |
111 | @media (max-width: 600px) {
112 | .grid {
113 | width: 100%;
114 | flex-direction: column;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/styles/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
6 | buntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
7 | /* font-family: Arial, Helvetica, sans-serif; */
8 | }
9 |
10 | h1{
11 | color: orange;
12 | }
13 |
14 | a {
15 | color: inherit;
16 | text-decoration: none;
17 | }
18 |
19 | * {
20 | box-sizing: border-box;
21 | }
22 |
23 | .bold{
24 | font-weight: bold;
25 | color: orange;
26 | }
27 |
28 | .container {
29 | display: flex;
30 | height: 100vh;
31 | }
32 |
33 | .controls {
34 | width: 20%;
35 | padding: 1rem;
36 | background: #14161a;
37 | color: #fff;
38 | overflow: auto;
39 | }
40 |
41 | .controls input {
42 | border: none;
43 | }
44 |
45 | .map-container {
46 | width: 100%;
47 | height: 100vh;
48 | }
49 |
50 | .hovering_over_message{
51 | position: absolute;
52 | z-index: 90000;
53 | left: 45%;
54 | background-color: orange;
55 | opacity: .6;
56 | font-size: 20px;
57 | padding: 15px;
58 | margin: 20px 0;
59 |
60 | border-radius: 5px;
61 | }
62 |
63 | .map {
64 | width: 80%;
65 | height: 100vh;
66 | }
67 |
68 | .highlight {
69 | font-size: 1.25rem;
70 | font-weight: bold;
71 | }
72 |
73 | .combobox-input {
74 | width: 100%;
75 | padding: 0.5rem;
76 | }
77 |
78 | .roof_panel_info_box{
79 | margin: 20px 0;
80 | padding: 5px 10px;
81 | /* border: 1px solid lightgray; */
82 | background-color: rgba(236, 236, 236, .3);
83 | border-radius: 5px;
84 |
85 | display: flex;
86 | flex-direction: column;
87 | }
88 |
89 | .roof_panel_info_box h1{
90 | font-size: 20px;
91 | margin-bottom: 10px;
92 | color: white;
93 | }
94 |
95 | .roof_panel_info_box p{
96 | margin-top: 0;
97 | }
98 |
99 | .delete_button{
100 | background-color: #F47174;
101 |
102 | font-size: 12px;
103 | border: none;
104 | padding: 5px 10px;
105 | border-radius: 5px;
106 |
107 | margin-bottom: 5px;
108 |
109 | color: white;
110 | }
111 |
112 | .deleted_panels_outer_container{
113 | display: flex;
114 | flex-wrap: wrap;
115 | align-items: center;
116 | }
117 |
118 | .deleted_panels_description{
119 | font-size: 10px;
120 | width: 30%;
121 | }
122 |
123 | .deleted_panels_inner_container{
124 | background-color: rgba(236, 112, 113, .6);
125 | padding: 5px;
126 | width: 70%;
127 | display: flex;
128 | flex-wrap: wrap;
129 | align-items: center;
130 | border-radius: 5px;
131 | }
132 |
133 | .deleted_panels_button{
134 | background-color: rgba(236, 112, 113, 1);
135 | border: none;
136 | color: white;
137 | margin: 3px 5px;
138 | padding: 3px 7px;
139 | border-radius: 5px;
140 |
141 | transition: .2s;
142 | }
143 |
144 | .deleted_panels_button:hover{
145 | opacity: .6;
146 | transition: .2s;
147 | }
148 |
--------------------------------------------------------------------------------
/components/map.tsx:
--------------------------------------------------------------------------------
1 | import { useState, useMemo, useCallback, useRef, useEffect } from "react";
2 | import {
3 | GoogleMap,
4 | Marker,
5 | DirectionsRenderer,
6 | Circle,
7 | MarkerClusterer,
8 | Polyline,
9 | Polygon,
10 | DrawingManager,
11 | useGoogleMap,
12 | } from "@react-google-maps/api";
13 | import Places from "./places";
14 | import { unmountComponentAtNode } from "react-dom";
15 | import React from "react";
16 | // import Distance from "./distance";
17 |
18 | type LatLngLiteral = google.maps.LatLngLiteral;
19 | type MapOptions = google.maps.MapOptions;
20 |
21 | export default function Map() {
22 | const [energyConsumption, setEnergyConsumption] = useStateFigure out how many solar panels you can fit on your roof.
382 |Draw polygons over all south, east and west facing sections of your roof.
391 | {deletedPanels.length > 0 &&Click to add panel back:
393 |Area: {area.toFixed(2)} ft²
408 | {panel.points.length === 3 &&Panels: {panel.solarPanels.length} solar panels
} 409 | 417 |Total Area: {getRoofArea().toFixed(2)} ft²
427 |Ender your home's average monthly energy consumption below:
428 |kWh per month
448 |450 | You can offset {(getRoofArea()/solarPanelArea*solarPanelEnergyOutput/energyConsumption*100).toFixed(0)}% of 451 | your home's energy using {(getRoofArea()/solarPanelArea).toFixed(0)} solar panels solar panels which 452 | will generate {(getRoofArea()/solarPanelArea*solarPanelEnergyOutput).toFixed(2)} kWh of energy 453 | per month. 454 |
455 |