diff --git a/index.html b/index.html index e4b78ea..28d14bb 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - Vite + React + TS + Lunar Vein: Arduino
diff --git a/src/App.tsx b/src/App.tsx index a64584f..86daeca 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,8 +1,12 @@ +import { BoardControllerProvider } from "./contexts/BoardController"; import MainPage from "./pages/MainPage"; +import "bootstrap-icons/font/bootstrap-icons.min.css"; function App () { return ( - + + + ) } diff --git a/src/components/forms/PinBox.tsx b/src/components/forms/PinBox.tsx new file mode 100644 index 0000000..dcb42d8 --- /dev/null +++ b/src/components/forms/PinBox.tsx @@ -0,0 +1,43 @@ +import { ChangeEventHandler, FormEventHandler, MouseEventHandler } from "react"; +import Switch from "./Switch"; + +interface PinBoxProps { + value: number | string; + state: boolean; + onValueChange?: ChangeEventHandler + onStateChange?: FormEventHandler +} + +function Add ({ onClick }: { onClick?: MouseEventHandler }) { + return ( + + ) +} + +function PinBox ({ value, state, onValueChange, onStateChange }: PinBoxProps) { + return ( +
+
+
Pin
+ +
+ +
+ ) +} + +PinBox.Add = Add; + +export default PinBox; \ No newline at end of file diff --git a/src/components/forms/Switch.tsx b/src/components/forms/Switch.tsx new file mode 100644 index 0000000..b5b4418 --- /dev/null +++ b/src/components/forms/Switch.tsx @@ -0,0 +1,13 @@ +import { FormEventHandler } from "react"; + +export default function Switch ({ state, onChange }: { state: boolean, onChange?: FormEventHandler }) { + return ( + + ) +} \ No newline at end of file diff --git a/src/components/landing/ControlLED.tsx b/src/components/landing/ControlLED.tsx new file mode 100644 index 0000000..f6b16f1 --- /dev/null +++ b/src/components/landing/ControlLED.tsx @@ -0,0 +1,57 @@ +import { useState } from "react"; +import PinBox from "../forms/PinBox"; +import { PinState } from "../../types/board"; +import { useLed } from "../../hooks"; + + +function ControlLED () { + const { addLed, getLed, leds, removeLed, setLed, setLedPin } = useLed(); + + const handleAdd = (): void => { + let anopin = 13; + for (let i = 0; i < leds.length; i++) { + // console.log(leds[i].pin != anopin, leds[i].pin, anopin); + if (leds[i].pin != anopin) break; + anopin--; + } + addLed(anopin, false); + } + + return ( +
+
+
+

+ LED +

+
+ {leds.map((led, i) => ( + { + const pin = e.target.value; + if (leds.filter(led => led.pin == pin).length > 0) { + alert(`Pin ${pin} is already use`); + return; + } + setLedPin(led.pin, pin); + }} + onStateChange={() => { + const state = !led.state; + setLed(led.pin, state); + }} + /> + ))} + {leds.length < 14 && } +
+
+
+
+ ) +} + +export default ControlLED; \ No newline at end of file diff --git a/src/components/landing/Hero.tsx b/src/components/landing/Hero.tsx index 81a4c1e..2098546 100644 --- a/src/components/landing/Hero.tsx +++ b/src/components/landing/Hero.tsx @@ -11,10 +11,10 @@ interface InHero { shortNav: ShortNav[] } -export default function Hero ({ img, shortNav }: InHero) { +function Hero ({ img, shortNav }: InHero) { return (
-
+

Lunar Vein: Arduino Client @@ -48,4 +48,6 @@ export default function Hero ({ img, shortNav }: InHero) {

) -} \ No newline at end of file +} + +export default Hero; \ No newline at end of file diff --git a/src/contexts/BoardController.tsx b/src/contexts/BoardController.tsx new file mode 100644 index 0000000..4164cdf --- /dev/null +++ b/src/contexts/BoardController.tsx @@ -0,0 +1,55 @@ +import { Dispatch, ReactNode, SetStateAction, createContext, useState } from "react"; +import { ChannelPinState, DynamicPinState, PinMode, PinState } from "../types/board"; + +interface ControllerContextProps { + pinModes: PinMode[]; + leds: PinState[]; + rgbLed: ChannelPinState[]; + piezo: DynamicPinState[]; + motoServo: DynamicPinState[]; + photoresistor: DynamicPinState[]; + setPinModes?: Dispatch>; + setLeds?: Dispatch>; + setRgbLed?: Dispatch>; + setPiezo?: Dispatch>; + setMotoServo?: Dispatch>; + setPhotoresistor?: Dispatch>; +} + +const INIT_VALUES: ControllerContextProps = { + pinModes: [], + leds: [ + { + pin: 13, + state: false + } + ], + rgbLed: [], + piezo: [], + motoServo: [], + photoresistor: [], +} + +export const BoardControllerContext = createContext(INIT_VALUES); + +export function BoardControllerProvider ({ children }: { children: ReactNode }) { + const [pinModes, setPinModes] = useState(INIT_VALUES.pinModes); + const [leds, setLeds] = useState(INIT_VALUES.leds); + const [rgbLed, setRgbLed] = useState(INIT_VALUES.rgbLed); + const [piezo, setPiezo] = useState(INIT_VALUES.piezo); + const [motoServo, setMotoServo] = useState(INIT_VALUES.motoServo); + const [photoresistor, setPhotoresistor] = useState(INIT_VALUES.photoresistor); + + const contextValue: ControllerContextProps = { + pinModes, setPinModes, + leds, setLeds, + rgbLed, setRgbLed, + piezo, setPiezo, + motoServo, setMotoServo, + photoresistor, setPhotoresistor + }; + + return + {children} + +} \ No newline at end of file diff --git a/src/css/index.css b/src/css/index.css index 40d2ebc..72e75db 100644 --- a/src/css/index.css +++ b/src/css/index.css @@ -4,7 +4,55 @@ @tailwind components; @tailwind utilities; +@layer base { + input::-webkit-outer-spin-button, + input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + + /* Firefox */ + input[type=number] { + -moz-appearance: textfield; + } +} + +@keyframes size-in { + from { transform: scale(0); } + to { transform: scale(1); } +} + +@keyframes fade-in { + from { opacity: 0; } + to { opacity: 1; } +} .container { @apply w-[1280px] mx-auto; +} + +.container-grid { + @apply grid grid-cols-8 gap-6; +} + +.switch { + @apply rounded-lg; +} +.switch > .handler { + @apply rounded-md p-[6px] transition-all; +} + + +.switch-on { + @apply border-primary bg-primary bg-opacity-40; +} +.switch-on > .handler { + @apply bg-primary ms-[50%]; +} + +.switch-off { + @apply border-disabled; +} +.switch-off > .handler { + @apply bg-disabled ms-0; } \ No newline at end of file diff --git a/src/data/control-navigation.json b/src/data/control-navigation.json index 4c55872..0bdd685 100644 --- a/src/data/control-navigation.json +++ b/src/data/control-navigation.json @@ -1,8 +1,4 @@ [ - { - "name": "Serial Monitor", - "target": "#serial-monitor" - }, { "name": "LED", "target": "#led" diff --git a/src/hooks/index.tsx b/src/hooks/index.tsx new file mode 100644 index 0000000..a0cbc07 --- /dev/null +++ b/src/hooks/index.tsx @@ -0,0 +1,43 @@ +import { useContext } from "react"; +import { BoardControllerContext } from "../contexts/BoardController"; + +export function usePin () { + return useContext(BoardControllerContext); +} + +export function useLed () { + const { leds, setLeds } = useContext(BoardControllerContext); + + const getLed = (pin: number | string) => { + const led = leds.find(val => val.pin == pin); + return led; + } + + const addLed = (pin: number | string, state?: boolean) => { + const newLed = [...leds, { pin, state: state || false }]; + setLeds!(newLed); + } + + const removeLed = (pin: number | string) => { + const newLed = leds.filter(led => led.pin != pin); + setLeds!(newLed); + } + + const setLed = (pin: number | string, state: boolean) => { + const newLed = leds.map(led => { + if (led.pin == pin) return { pin, state }; + return led; + }) + setLeds!(newLed); + } + + const setLedPin = (pin: number | string, newPin: number | string) => { + const newLed = leds.map(led => { + if (led.pin == pin) return { pin: newPin, state: led.state }; + return led; + }) + setLeds!(newLed); + } + + return { leds, getLed, setLed, setLedPin, addLed, removeLed }; +} \ No newline at end of file diff --git a/src/pages/MainPage.tsx b/src/pages/MainPage.tsx index 59a0c28..560b2a8 100644 --- a/src/pages/MainPage.tsx +++ b/src/pages/MainPage.tsx @@ -1,5 +1,8 @@ import MainBody from "../components/MainBody"; + +// Section components import Hero from "../components/landing/Hero"; +import ControlLED from "../components/landing/ControlLED"; import LunarImg from "../assets/img/ocs/lunar-oc.png"; @@ -12,6 +15,7 @@ function MainPage () { img={LunarImg} shortNav={ControlNav} /> + ) } diff --git a/src/types/board.ts b/src/types/board.ts new file mode 100644 index 0000000..f9cdb9d --- /dev/null +++ b/src/types/board.ts @@ -0,0 +1,20 @@ +export type PinMode = { + pin: string | number, + mode: 'INPUT' | 'OUTPUT' | 'SERVO' +} + +export type PinState = { + pin: number | string, + state: boolean +} + +export type DynamicPinState = { + pin: string | number, + state: number +} + +export interface ChannelPinState { + red: PinState, + green: PinState, + blue: PinState +} \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js index 467db1a..66f7f83 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -9,7 +9,9 @@ export default { colors: { 'primary': '#3A3AFF', 'secondary': '#0B0B1D66', + 'secondary-solid': '#0B0B1D', 'finn': '#00000066', + 'finn-solid': '#000000', 'danger': '#FF016C', 'disabled': '#7373B0', 'border': '#FFFFFF66', @@ -18,6 +20,10 @@ export default { fontFamily: { 'poppins': '"Poppins", sans-serif', 'roboto-mono': '"Roboto Mono", monospace', + }, + animation: { + 'size-in': 'size-in .3s ease-in-out', + 'fade-in': 'fade-in .3s ease-in-out' } }, },