Git URL : https://github.com/avinashkumar-github/indecision-app-using-react-js


import React from "react";

import ReactDOM from 'react-dom/client';    


///////////////Add minus and reset using function //////////////////////////////////
   
    let count = 0;
    const addOne = () => {
        count++;
        console.log("Add one", count)
        renderCount()
    }

    const minusOne = () => {        
        console.log("Minus One")
        if(count > 0) {
            count--;
        }      
        renderCount()
    }

    const reset = () => {
        console.log("Reset")
        count = 0;
        renderCount()
    }



    const root = ReactDOM.createRoot(document.getElementById("root"));

    function renderCount(){
        const template = (
            <div>
                <h1>Count : {count}</h1>
                <button onClick={addOne}>+1</button>
                <button onClick={minusOne} >-1</button>
                <button onClick={reset}>Reset</button>
            </div>
        );
        root.render(template)
    }
             
   
renderCount();



////////////////  END/////////////////////////////////////////




//-----------Task 2 ----------Indecision App START using function-----------------


const app = {
    title: 'Indecision App',
    subtitle: "Subtitle App",
    options: []
}


const onFormSubmit = (e) => {

    e.preventDefault();

    const option = e.target.elements.option.value;
    if(option){
        app.options.push(option)
        renderApp();
    }
   
   
}

const getOptions = () => {

    return app.options.map((option)=>{
        return <li key = {option}> {option}</li>;
    })
}


const removeAll = () => {
    app.options = [];
    renderApp();
}


const selectRandomOption = () => {    
    const randomNum = Math.floor(Math.random() * app.options.length);
    alert(app.options[randomNum]);
}


const root = ReactDOM.createRoot(document.getElementById("root"));

function renderApp(){
    const template = (
        <div>
            <h1>{app.title}</h1>
            <h4>{app.subtitle &&  <p>{app.subtitle}</p>}</h4>
            <p>{app.options.length ?  'Options listed'  :'No items yet added'}</p>    
            <ol>{getOptions()}</ol>    
            <form onSubmit={onFormSubmit}>
                <input type="text" name="option" />
                <button>Add</button>
            </form>
            <button onClick={removeAll}>Remove all</button>
            <button disabled={app.options.length === 0} onClick={selectRandomOption}>What should I do ?</button>
        </div>
   
    )
   
    root.render(template)
}



renderApp();


//-----------Task 2 ----------Indecision App END-----------------



///----------------TOGGLE APP START-------------------------------

let visible = false;
const displayBlock = (<p>Here are the details</p>)

const toggleDetail = () => {
    visible = visible ? false : true;
    //visible = !visible
    reRenderApp();


}


const root = ReactDOM.createRoot(document.getElementById("root"));
const reRenderApp = () => {
    const template = (
        <div>
            <h1>Toggle App</h1>
            <button onClick={toggleDetail}>{visible ? 'Hide' : 'Show' }</button>
            {visible && displayBlock}
        </div>
    );
       
    root.render(template)
}


reRenderApp();


///----------------TOGGLE APP END-------------------------------



// USING CLASS TASK ONE START-------------------------------

class Person {
    constructor(name = "Anonymous", age= 0) {
        this.name = name;
        this.age = age;
    }

    getGreeting () {
        return `Hi I am ${this.name} with ${this.age} year(s) old.`
    }
}


class Student extends Person {
    constructor(name, age, subject) {
        super(name, age);
        this.subject = subject;
    }

    hasSubject() {
        return !!this.subject
    }

    getDescription () {
        let description = super.getGreeting();
        if(this.hasSubject()){
            description += ` And the subject is  ${this.subject}`
        }
        return description;
    }
}

const me = new Person("Avinash", 32);
console.log(me.getGreeting());

const other = new Person();
console.log(other.getGreeting())

const sub = new Student("Avinash", 32, 'Computer');
console.log(sub.getDescription())


// CLASS TASK ONE END-------------------------------



// // CLASS TASK TWO START INDECISION APP-------------------------------


class Indecision extends React.Component
{
    // testVar = "thisis a test";

    // testV = () => {
    //     this.testVar;
    // }
    constructor (props) {
        super(props);
        this.handleRemoveAll = this.handleRemoveAll.bind(this);
        this.handleAction = this.handleAction.bind(this);
        this.handleForm = this.handleForm.bind(this);
        this.removeSingleOption = this.removeSingleOption.bind(this)
        this.state = {
            options : [],// now reading from local storage, so no mre empty while loading
            error: undefined
        }
    }

    handleRemoveAll () {
        // this.setState(()=>{
        //     return {
        //         options: []
        //     }
        // })

        this.setState(()=> ({ options: [] }))
    }

    handleAction (){
        let randomNum = Math.floor(Math.random() * this.state.options.length);
        alert(this.state.options[randomNum])
    }

    handleForm (e) {
        e.preventDefault();
        const option = e.target.elements.option.value.trim();
        e.target.elements.option.value = '';
        if(option){
            this.setState((prevState)=>{
                return {
                    options: prevState.options.concat(option),
                    error: prevState.error = undefined
                }
            })
        }else{
            this.setState((prevState)=>{
                return {
                    error : prevState.error = 'Error in adding option'
                }
            })
        }
    }


    removeSingleOption (opt) {
        this.setState((prevState)=>{
            return {
                options: prevState.options.filter((option)=>{
                    return opt !==option
                })
            }
        })
    }

    render() {
        // const title = "Indecision";
        const subtitle = 'A place for decision';        
        return (
            <div>
                <Header subtitle={subtitle}/>
                <Action handleAction={this.handleAction} hasOptions={this.state.options.length > 0}/>
                <Options  options={this.state.options} handleRemoveAll = {this.handleRemoveAll} removeSingleOption = {this.removeSingleOption}/>
                <Form handleForm={this.handleForm} formError={this.state.error} />
            </div>
        )
    }

    componentDidMount() {

        const json = localStorage.getItem("options");
        const options = JSON.parse(json);
        if(options){
            this.setState(()=>({options}))
        }
    }

    componentDidUpdate(prevProps, prevState) {
        if(prevState.options.length !== this.state.options.length){
            const json = JSON.stringify(this.state.options);
            localStorage.setItem("options", json);
        }
    }

    // componentWillUnmount() {

    // }
}



// Class based component
// class Header extends React.Component
// {
//     render() {
//         return (
//             <div>
//                 <h1>{this.props.title}</h1>
//                 <h2>{this.props.subtitle}</h2>
//             </div>
//         )
//     }
// }


// Function based Component
const Header = (props) => {
    return (
        <div>
            <h1>{props.title}</h1>
            {props.subtitle && <h2>{props.subtitle}</h2>}
        </div>
    )
}

//Default Props
Header.defaultProps = {
    title: "Indecision"
}


// class Action extends React.Component
// {
//     // handleAction () {
//     //     alert('hello')
//     //     console.log(this.props.options)
//     // }

//     render() {
//         return (
//             <div>
//                 <button onClick={this.props.handleAction}
disabled={!this.props.hasOptions}>This is a Action component</button>
//             </div>
//         );
//     }
// }

const Action = (props) => {
    return (
        <div>
            <button onClick={props.handleAction}
            disabled={!props.hasOptions}>This is a Action component</button>
        </div>
    );
}

class Options extends React.Component
{
    // handleRemoveAll () {
    //     alert("remove")
    // }
    render() {
        return (
            <div>
                <button onClick={this.props.handleRemoveAll}>Remove All</button>
                <p>This is Options component</p>  
                <Option optionList={this.props.options}
                 removeSingleOption = {this.props.removeSingleOption}/>
            </div>        
        );
    }
}


class Option extends React.Component
{
    constructor(props){
        super(props);
        this.getList = this.getList.bind(this)
    }

    getList() {
        return this.props.optionList.map((opt)=>{
            return <li key={opt}>{opt} <button onClick={(e)=>{
                this.props.removeSingleOption(opt)
            }}>Remove</button></li>
        })
    }
   
    render(){
        return (
            <ol>                
                {this.getList()}
            </ol>
        )
    }
}

class Form extends React.Component
{
   

    render() {
        return (
            <form onSubmit={this.props.handleForm}>
                <p>{this.props.formError}</p>
                <input type="text" name="option" />
                <button type="submit">Add</button>
            </form>
        );
    }
}


const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Indecision />);



// //----------CLASS TASK TWO END-------------------------------------





////----COUNTER APP USING CLASS Component START

class Counter extends React.Component
{
    constructor(props){
        super(props);
        this.addOne = this.addOne.bind(this);
        this.minusOne = this.minusOne.bind(this);
        this.reset = this.reset.bind(this);
        this.state = {
            count : 0
        }
    }

    addOne() {
        this.setState((prevState)=>{
            return {
                count : prevState.count + 1
            }            
        })
    }

    minusOne() {
        if(this.state.count > 0) {
            this.setState((prevState)=>{
                return {
                    count : prevState.count - 1
                }
            })
        }        
    }

    reset () {
        this.setState((prevState)=>{
            return {
                count: 0
            }
        })
    }

    render() {
        return (
            <div>
                <h1>Count : {this.state.count}</h1>
                <button onClick={this.addOne}>+1</button>
                <button onClick={this.minusOne}>-1</button>
                <button onClick={this.reset}>Reset</button>
            </div>
        );
    }
}

const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<Counter />)




// //----COUNTER APP USING CLASS Component END