article

Tuesday, November 9, 2021

SwiftUI Firebase Grocery Shopping List App

SwiftUI Firebase Grocery Shopping List App
ContentView.swift
 
//
//  ContentView.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import Firebase
import FirebaseFirestoreSwift

struct ContentView: View {
    
    private var db: Firestore
    @State private var storeName: String = ""
    @State private var stores: [Store] = []
    
    init() {
        db = Firestore.firestore()
    }
    
    private func saveStore(store: Store) {
        _ = try? db.collection("stores")
            .addDocument(from: store) { error in
                if let error = error {
                    print(error.localizedDescription)
                } else {
                    print("Document has been saved!")
                    getAllStores()
                }
                
            }
    }
    
    private func getAllStores() {
        
        db.collection("stores")
            .getDocuments { (snapshot, error) in
                if let error = error {
                    print(error.localizedDescription)
                } else {
                    if let snapshot = snapshot {
                        stores = snapshot.documents.compactMap { doc in
                            var store = try? doc.data(as: Store.self)
                            if store != nil {
                                store!.id = doc.documentID
                            }
                            return store
                        }
                    }
                }
            }
        
    }
    
    private func deleteStore(at indexSet: IndexSet) {
        indexSet.forEach { index in
            
            let store = stores[index]
            // delete from the firestore database
            db.collection("stores")
                .document(store.id!)
                .delete { error in
                    if let error = error {
                        print(error.localizedDescription)
                    } else {
                        getAllStores()
                    }
                }
            
        }
    }
    
    var body: some View {
        
        NavigationView {
            
            VStack {
                TextField("Enter store name", text: $storeName)
                    .font(.title2)
                    .modifier(customViewModifier(roundedCornes: 6, startColor: .orange, endColor: .purple, textColor: .white))
                Button("Save Store") {
                    saveStore(store: Store(name: storeName))
                }
                .frame(width: 200)
                .padding()
                .foregroundColor(.white)
                .background(Color.orange)
                .cornerRadius(40)
                
                List {
                    
                    ForEach(stores, id: \.name) { store in
                        NavigationLink(
                            destination: StoreDetailsView(store: store))
                        {
                            Text(store.name)
                        }
                    }.onDelete(perform: deleteStore)
                }.listStyle(PlainListStyle())
                
                Spacer()
                    
                    .onAppear(perform: {
                        getAllStores()
                    })
                
            }.padding()
            
            .navigationTitle("Grocery")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


struct customViewModifier: ViewModifier {
    var roundedCornes: CGFloat
    var startColor: Color
    var endColor: Color
    var textColor: Color
    
    func body(content: Content) -> some View {
        content
            .padding()
            .background(LinearGradient(gradient: Gradient(colors: [startColor, endColor]), startPoint: .topLeading, endPoint: .bottomTrailing))
            .cornerRadius(roundedCornes)
            .padding(3)
            .foregroundColor(textColor)
            .overlay(RoundedRectangle(cornerRadius: roundedCornes)
                        .stroke(LinearGradient(gradient: Gradient(colors: [startColor, endColor]), startPoint: .topLeading, endPoint: .bottomTrailing), lineWidth: 2.5))
            .font(.custom("Open Sans", size: 18))
            
            .shadow(radius: 10)
    }
}
StoreDetailsView.swift
 
//
//  StoreDetailsView.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import Firebase
import FirebaseFirestoreSwift

struct StoreDetailsView: View {
    
    @State var store: Store
    @State private var storeName: String = ""
    @State private var groceryItemName: String = ""
    let db = Firestore.firestore()
    
    private func updateStore() {
        
        db.collection("stores")
            .document(store.id!)
            .updateData(["name": storeName]) { error in
                
                if let error = error {
                    print(error.localizedDescription)
                } else {
                    print("Store has been updated!")
                }
            }
        
    }
    
    private func loadGroceryItems() {
        let ref = db.collection("stores")
            .document(store.id!)
        
        ref.getDocument { doc, error in
            if let doc = doc, doc.exists {
                if let store = try? doc.data(as: Store.self) {
                    self.store = store
                    self.store.id = doc.documentID
                }
            } else {
                print("Document does not exists!")
            }
        }
        
    }
    
    private func saveGroceryItem() {
        
        db.collection("stores")
            .document(store.id!)
            .updateData([
                "items": FieldValue.arrayUnion([groceryItemName])
            ]) { error in
                if let error = error {
                    print(error.localizedDescription)
                } else {
                    // load the docs and populate the items
                    loadGroceryItems()
                }
            }
        
    }
    
    var body: some View {
       
        NavigationView {
            VStack {
                TextField("Enter item name", text: $groceryItemName)
                    .font(.title2)
                    .modifier(customViewModifier(roundedCornes: 6, startColor: .orange, endColor: .purple, textColor: .white))
                
                Button("Add Item") {
                    saveGroceryItem()
                }
                .frame(width: 200)
                .padding()
                .foregroundColor(.white)
                .background(Color.orange)
                .cornerRadius(40)
                
                if let items = store.items {
                    List(items, id: \.self) { item in
                        Text(item)
                    }.listStyle(GroupedListStyle())
                }
                
                Spacer()
                
            }.padding()
        }.navigationTitle(store.name)
    }
}

struct StoreDetailsView_Previews: PreviewProvider {
    static var previews: some View {
        StoreDetailsView(store: Store(id: "333", name: "HEB"))
    }
}
Store.swift
 
//
//  Store.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import Foundation

struct Store: Codable {
    var id: String?
    let name: String
    var items: [String]? = nil
}
DevSwiftUIApp.swift
 
//
//  DevSwiftUIApp.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import Firebase

@main
struct DevSwiftUIApp: App {
       
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
      
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
  
class AppDelegate: NSObject,UIApplicationDelegate{
        
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
            
        FirebaseApp.configure()
        return true
    }
}

Monday, November 8, 2021

ReactJS Progress Bar - Bootstrap Progress Bar

ReactJS Progress Bar - Bootstrap Progress Bar

Install bootstrap

npm install react-bootstrap bootstrap@5.1.3

C:\reactdev\myreactdev>npm install react-bootstrap bootstrap@5.1.3

https://react-bootstrap.github.io/getting-started/introduction/

src/index.js
//src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
public/index.html
//public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>ReactJS </title>
  </head>
  <body>
    <div id="root"></div>
</body>
</html>
src/App.js src/App.js
//src/App.js
import React, { useEffect, useState  } from 'react';

let progressInterval = null;

function App() {
  const [progress, setProgress] = useState(0);

  useEffect(() => {
    progressInterval = setInterval(() => {
      setProgress(prev => prev + 1);
    }, 100);
  }, []);

  useEffect(() => {
    if (progress >= 100) {
      clearInterval(progressInterval);
    }
  }, [progress]);

  return (
    <div className="m-5">
      <h5 className="mb-3">ReactJS Progress Bar - Bootstrap Progress Bar</h5>
      <div className="progress w-50" style={{ height: 30 }}>
        <div className="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style={{ width: `${progress}%` }}>{progress}%</div>
      </div>
    </div>
  );
}

export default App;

SwiftUI Custom Sheets Quarter, Half and Full Sheets

SwiftUI Custom Sheets Quarter, Half and Full Sheets

ContentView.swift
 
//
//  ContentView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @State private var sheetMode: SheetMode = .none
    
    var body: some View {
        ZStack {
            SheetView(sheetMode: $sheetMode) {
                
                if sheetMode == .quarter {
                    VStack {
                        Text("Hello World! Sheets in SwiftUI")
                            .font(.body).foregroundColor(.white)
                        Spacer()
                    }
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .background(Color.yellow)
                    .clipShape(RoundedRectangle(cornerRadius: 25.0, style: .continuous))
                }else if sheetMode == .half {
                    VStack {
                        Text("Hello World! Sheets in SwiftUI")
                            .foregroundColor(.white)
                        Spacer()
                    }
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .background(Color.green)
                    .clipShape(RoundedRectangle(cornerRadius: 25.0, style: .continuous))
                }else if sheetMode == .full {
                    VStack {
                        Text("Hello World! Sheets in SwiftUI")
                            .foregroundColor(.white)
                    }
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .background(Color.orange)
                    .clipShape(RoundedRectangle(cornerRadius: 25.0, style: .continuous))
                }else {
                    VStack {
                        Text("Hello World! Sheets in SwiftUI")
                            .foregroundColor(.white)
                    }
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .background(Color.red)
                    .clipShape(RoundedRectangle(cornerRadius: 25.0, style: .continuous))
                }
                
            }
            
            VStack {
                Button(action: {
                    sheetMode = .quarter
                }) {
                    HStack {
                        Text("Show Quater")
                            .font(.system(size: 18))
                            .fontWeight(.bold)
                    }
                    .frame(width: 200)
                    .padding()
                    .foregroundColor(.white)
                    .background(Color.yellow)
                    .cornerRadius(40)
                }
                
                Button(action: {
                    sheetMode = .half
                }) {
                    HStack {
                        Text("Show half")
                            .font(.system(size: 18))
                            .fontWeight(.bold)
                    }
                    .frame(width: 200)
                    .padding()
                    .foregroundColor(.white)
                    .background(Color.green)
                    .cornerRadius(40)
                }
                
                Button(action: {
                    sheetMode = .full
                }) {
                    HStack {
                        Text("Show full")
                            .font(.system(size: 18))
                            .fontWeight(.bold)
                    }
                    .frame(width: 200)
                    .padding()
                    .foregroundColor(.white)
                    .background(Color.orange)
                    .cornerRadius(40)
                }
                
                Button(action: {
                    sheetMode = .none
                }) {
                    HStack {
                        Text("Show none")
                            .font(.system(size: 18))
                            .fontWeight(.bold)
                    }
                    .frame(width: 200)
                    .padding()
                    .foregroundColor(.white)
                    .background(Color.red)
                    .cornerRadius(40)
                }
                
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
SheetView.swift
 
//
//  SheetView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct SheetView<Content: View>: View {

    let content: () -> Content
    var sheetMode: Binding<SheetMode>
    
    init(sheetMode: Binding<SheetMode>, @ViewBuilder content: @escaping () -> Content) {
        
        self.content = content
        self.sheetMode = sheetMode
        
    }
    
    private func calculateOffset() -> CGFloat {
        
        switch sheetMode.wrappedValue {
            case .none:
                return UIScreen.main.bounds.height
            case .quarter:
                return UIScreen.main.bounds.height - 200
            case .half:
                return UIScreen.main.bounds.height/2
            case .full:
                return 0
        }
        
    }
    
    var body: some View {
        content()
            .offset(y: calculateOffset())
            .animation(.spring())
            .edgesIgnoringSafeArea(.all)
    }
}

struct SheetView_Previews: PreviewProvider {
    static var previews: some View {
        SheetView(sheetMode: .constant(.none)) {
            VStack {
                Text("Hello World")
            }.frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(Color.blue)
            .clipShape(RoundedRectangle(cornerRadius: 25.0, style: .continuous))
        }
    }
}

enum SheetMode {
    case none
    case quarter
    case half
    case full
}

Sunday, November 7, 2021

SwiftUI Pull to Refresh

SwiftUI Pull to Refresh

In this tutorial I will demonstrate how to use the pull to refresh feature in SwiftUI.

 
//
//  ContentView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {

    @State private var posts = [
        NewsItem(id: 0, title: "Want the latest posts?", body: "Pull to refresh!")
    ]
    
    var body: some View {
        NavigationView {
            List(posts) { item in
                VStack(alignment: .leading) {
                    Text(item.title)
                        .font(.headline)
                    Text(item.body)
                        .foregroundColor(.secondary)
                }
            }
            .refreshable {
                do {
                    // Fetch and decode JSON into posts items

                    let url = URL(string: "https://jsonplaceholder.typicode.com/posts")!
                    let (data, _) = try await URLSession.shared.data(from: url)
                    posts = try JSONDecoder().decode([NewsItem].self, from: data)
                } catch {
                    // Something went wrong; clear the news
                    posts = []
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct NewsItem: Decodable, Identifiable {
    let id: Int
    let title: String
    let body: String
}

ReactJS How to Make A React Bootstrap Modal

ReactJS How to Make A React Bootstrap Modal

Install bootstrap

npm install react-bootstrap bootstrap@5.1.3

C:\reactdev\myreactdev>npm install react-bootstrap bootstrap@5.1.3

https://react-bootstrap.github.io/getting-started/introduction/

src/index.js
//src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
public/index.html
//public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>ReactJS </title>
  </head>
  <body>
    <div id="root"></div>
</body>
</html>
src/App.js
//src/App.js
import React, {useState} from "react";
import 'bootstrap/dist/css/bootstrap.min.css';
import {Modal, Button} from 'react-bootstrap';

function App() {
	const [show, setShow] = useState(false);
	const handleClose = () => setShow(false);
	const handleShow = () => setShow(true);
	return (
		<div className="container"><h1>ReactJS How to Make A React Bootstrap Modal</h1>
		<Button className="nextButton" onClick={handleShow}>
		  Open Modal
		</Button>
		
		<Modal show={show} onHide={handleClose} >
		  <Modal.Header>
			<Modal.Title>Modal heading</Modal.Title>
		  </Modal.Header>
		  <Modal.Body>Woohoo, you're reading this text in a modal! Size : size="lg", size="sm"</Modal.Body>
		  <Modal.Footer>
			<Button variant="secondary" onClick={handleClose}>
			  Close
			</Button>
			<Button variant="primary" onClick={handleClose}>
			  Save Changes
			</Button>
		  </Modal.Footer>
		</Modal>

	  </div>
	);
  }

export default App;

Saturday, November 6, 2021

ReactJS How to use AJAX in React HTTP GET Request

ReactJS How to use AJAX in React HTTP GET Request

In this tutorial I'm going to show how to use ajax HTTP GET request without third party library using XMLHttpRequest()

json : https://jsonplaceholder.typicode.com/users

Install bootstrap

npm install react-bootstrap bootstrap@5.1.3

C:\reactdev\myreactdev>npm install react-bootstrap bootstrap@5.1.3

https://react-bootstrap.github.io/getting-started/introduction/

src/index.js
//src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css'

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
public/index.html
//public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>ReactJS </title>
  </head>
  <body>
    <div id="root"></div>
</body>
</html>
src/App.js
//src/App.js
import React from 'react';

class App extends React.Component {
	
	constructor (props) {
		super(props)
		this.state = {error: null, users: []};
		this.headers = [
			{ key: 'id', label: 'ID' },
			{ key: 'name', label: 'Name' },
			{ key: 'username', label: 'User name' },
			{ key: 'email', label: 'Email' }
		];
	}
	
	componentDidMount () {
		var request = new XMLHttpRequest(); //XMLHttpRequest for fetching data instead of Fetch API (fetch())
		
		request.open('GET', 'https://jsonplaceholder.typicode.com/users', true);
		
		request.onload = () => {
			if (request.readyState === 4 && request.status === 200) {
				this.setState({users: JSON.parse(request.responseText)}) //use setState() to update your component when the data is retrieved.
			} else {
				//Error
			}
		};
		
		request.onerror = (err) => {
			this.setState({error: err})
		};
		
		request.send();
	}
	
	render() {
		if (this.state.error) {
			return <div>Error: {this.state.error.message}</div>;
		} else {
			return (
				<div className="container"><h1>ReactJS How to use AJAX in React HTTP GET Request</h1>
				<table className="table table-bordered table-striped">
					<thead>
						<tr>
						{
							this.headers.map(function(h) {
								return (
									<th key = {h.key}>{h.label}</th>
								)
							})
						}
						</tr>
					</thead>
					<tbody>
						{
							this.state.users.map(function(item, key) {
								return (
									<tr key = {key}>
									  <td>{item.id}</td>
									  <td>{item.name}</td>
									  <td>{item.username}</td>
									  <td>{item.email}</td>
									</tr>
								)
							})
						}
					</tbody>
				</table>
			</div>	
			)
		}
	}
}
export default App;

ReactJS Fetch Data from Database with PHP Mysql

ReactJS Fetch Data from Database with PHP Mysql

Install bootstrap

npm install react-bootstrap bootstrap@5.1.3

C:\reactdev\myreactdev>npm install react-bootstrap bootstrap@5.1.3

https://react-bootstrap.github.io/getting-started/introduction/

Database Table

CREATE TABLE `employee` (
  `id` int(11) NOT NULL,
  `name` varchar(100) NOT NULL,
  `position` varchar(100) NOT NULL,
  `office` varchar(100) NOT NULL,
  `age` int(11) NOT NULL,
  `salary` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `employee`
--

INSERT INTO `employee` (`id`, `name`, `position`, `office`, `age`, `salary`) VALUES
(1, 'Tiger Wood', 'Accountant', 'Tokyo', 36, 5689),
(2, 'Mark Oto Ednalan', 'Chief Executive Officer (CEO)', 'London', 56, 5648),
(3, 'Jacob thompson', 'Junior Technical Author', 'San Francisco', 23, 5689),
(4, 'cylde Ednalan', 'Software Engineer', 'Olongapo', 23, 54654),
(5, 'Rhona Davidson', 'Software Engineer', 'San Francisco', 26, 5465),
(6, 'Quinn Flynn', 'Integration Specialist', 'New York', 53, 56465),
(8, 'Tiger Nixon', 'Software Engineer', 'London', 45, 456),
(9, 'Airi Satou updated', 'Pre-Sales Support updated', 'New York', 25, 4568),
(10, 'Angelica Ramos updated', 'Sales Assistant updated', 'New York', 45, 456),
(11, 'Ashton updated', 'Senior Javascript Developer', 'Olongapo', 45, 54565),
(12, 'Bradley Greer', 'Regional Director', 'San Francisco', 27, 5485),
(13, 'Brenden Wagner', 'Javascript Developer', 'San Francisco', 38, 65468),
(14, 'Brielle Williamson', 'Personnel Lead', 'Olongapo', 56, 354685),
(15, 'Bruno Nash', 'Customer Support', 'New York', 36, 65465),
(16, 'cairocoders', 'Sales Assistant', 'Sydney', 45, 56465),
(17, 'Zorita Serrano', 'Support Engineer', 'San Francisco', 38, 6548),
(18, 'Zenaida Frank', 'Chief Operating Officer (COO)', 'San Francisco', 39, 545),
(19, 'Sakura Yamamoto', 'Support Engineer', 'Tokyo', 48, 5468),
(20, 'Serge Baldwin', 'Data Coordinator', 'Singapore', 85, 5646),
(21, 'Shad Decker', 'Regional Director', 'Tokyo', 45, 4545);

ALTER TABLE `employee`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `employee`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=22;

src/index.js
//src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css'

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
public/index.html
//public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>ReactJS </title>
  </head>
  <body>
    <div id="root"></div>
</body>
</html>
src/App.js
//src/App.js
import React from 'react';

class App extends React.Component {
	constructor(props) {
		super(props);
		this.state = {employee: []};
		this.headers = [
			{ key: 'id', label: 'Id'},
			{ key: 'name', label: 'Name' },
			{ key: 'position', label: 'Position' },
			{ key: 'office', label: 'Office' },
			{ key: 'age', label: 'Age' },
			{ key: 'salary', label: 'Salary' }
		];
		this.state = { checkedBoxes: []	};
		this.deleteEmployee = this.deleteEmployees.bind(this);
		this.toggleCheckbox = this.toggleCheckbox.bind(this);
	}
	
	deleteEmployees = (event) => {
		event.preventDefault();
		if(window.confirm('Are you sure, want to delete the selected employee?')) {
			alert(this.state.checkedBoxes + " Succesfully Deleted");
		}
	}
	
	toggleCheckbox = (e, item) => {		
		if(e.target.checked) {
			let arr = this.state.checkedBoxes;
			arr.push(item.id);
			
			this.setState = { checkedBoxes: arr};
		} else {			
			let items = this.state.checkedBoxes.splice(this.state.checkedBoxes.indexOf(item.id), 1);
			
			this.setState = {
				checkedBoxes: items
			}
		}		
		console.log(this.state.checkedBoxes);
	}
	
	componentDidMount() {
		fetch('http://localhost/devtest/reactjs/employee.php/').then(response => {
			console.log(response);
			return response.json();
		  }).then(result => {
			// Work with JSON data here
			console.log(result);
			this.setState({
				employee_rs:result
			});	
		  }).catch(err => {
			// Do something for an error here
			console.log("Error Reading data " + err);
		  });
	}
		
	render() {
		const employeeFound = this.state.employee_rs && this.state.employee_rs.length;
		if(employeeFound) {
			return (
				<div className="container"><h1>ReactJS Fetch Data from Database with PHP Mysql</h1>
					<div id="msg"></div>
					<button type="button" className="btn btn-danger" onClick={this.deleteEmployees}>Delete Selected Employee(s)</button>
					<table className="table table-bordered table-striped">
						<thead>
							<tr>
								{
									this.headers.map(function(h) {
										return (
											<th key={h.key}>{h.label}</th>
										)
									})
								}
							</tr>
						</thead>
						<tbody>
							{
								this.state.employee_rs.map(function(item, index) {
								return (
									<tr key={index}>
									  <td><input type="checkbox" className="selectsingle" value="{item.id}" checked={this.state.checkedBoxes.find((p) => p.id === item.id)} onChange={(e) => this.toggleCheckbox(e, item)}/>
									    {item.id}
									  </td>
									  <td>{item.name}</td>
									  <td>{item.position}</td>
									  <td>{item.office}</td>
									  <td>{item.age}</td>
									  <td>{item.salary}</td>
									</tr>
								)}.bind(this))
							}
						</tbody>
					</table>
				</div>
			)
		} else {
			return (
				<div id="container">
					No product found
				</div>
			)
		}
	}
}
export default App;
http://localhost/devtest/reactjs/employee.php
//http://localhost/devtest/reactjs/employee.php
<?php
header("Access-Control-Allow-Origin: *"); //add this CORS header to enable any domain to send HTTP requests to these endpoints:
$host = "localhost"; 
$user = "root"; 
$password = ""; 
$dbname = "testingdb"; 
$id = '';

$con = mysqli_connect($host, $user, $password,$dbname);

$method = $_SERVER['REQUEST_METHOD'];


if (!$con) {
  die("Connection failed: " . mysqli_connect_error());
}


switch ($method) {
    case 'GET':
      $sql = "select * from employee"; 
      break;
}

// run SQL statement
$result = mysqli_query($con,$sql);

// die if SQL statement failed
if (!$result) {
  http_response_code(404);
  die(mysqli_error($con));
}

if ($method == 'GET') {
    if (!$id) echo '[';
    for ($i=0 ; $i<mysqli_num_rows($result) ; $i++) {
      echo ($i>0?',':'').json_encode(mysqli_fetch_object($result));
    }
    if (!$id) echo ']';
}else {
    echo mysqli_affected_rows($con);
}

$con->close();

ReactJS Dependent Dropdown - Country, State and City

ReactJS Dependent Dropdown - Country, State and City

Install bootstrap

npm install react-bootstrap bootstrap@5.1.3

C:\reactdev\myreactdev>npm install react-bootstrap bootstrap@5.1.3

https://react-bootstrap.github.io/getting-started/introduction/

src/index.js
//src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css'

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
public/index.html
//public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>ReactJS </title>
  </head>
  <body>
    <div id="root"></div>
</body>
</html>
src/App.js
//src/App.js
import React from 'react';

class App extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			countries : [],
			states : [],
			cities : [],
			selectedCountry : 'Country',
			selectedState : 'State'
		};
		this.changeCountry = this.changeCountry.bind(this);
		this.changeState = this.changeState.bind(this);
	}
  
	componentDidMount() { //https://reactjs.org/docs/react-component.html#componentdidmount
		this.setState({
			countries : [
				{ name: 'Philippines', states: [ 
					{name: 'Central Luzon', cities: ['Angeles City', 'Olongapo', 'San Fernando']},
					{name: 'NCR', cities: ['Pasay City', 'Makati', 'Marikina']}
				]},
				{ name: 'United States of America', states: [ 
					{name: 'California', cities: ['Sacramento', 'Los Angeles', 'Bakersfield', 'Carson']},
					{name: 'Florida', cities: ['Tallahassee', 'Jacksonville']},
					{name: 'Illinois', cities: ['Springfield', 'Chicago']},
					{name: 'New Jersey', cities: ['Trenton', 'Newark']}
				]},
					
			]
		});
	}
  
	changeCountry(event) {
		this.setState({selectedCountry: event.target.value});
		this.setState({states : this.state.countries.find(cntry => cntry.name === event.target.value).states});
	}

	changeState(event) {
		this.setState({selectedState: event.target.value});
		const stats = this.state.countries.find(cntry => cntry.name === this.state.selectedCountry).states;
		this.setState({cities : stats.find(stat => stat.name === event.target.value).cities});
	}
	
	render() {
		return (
			<div className="container">
				<div className="row">
				<h2>ReactJS Dependent Dropdown - Country, State and City</h2>
	
				<div className="form-group">
					<label style={styles.lbl}>Country</label>
					<select className="form-select" placeholder="Country" value={this.state.selectedCountry} onChange={this.changeCountry}>
						<option>Country</option>
						{this.state.countries.map((e, key) => {
							return <option key={key}>{e.name}</option>;
						})}
					</select>
				</div>

				<div className="form-group">
					<label style={styles.lbl}>State</label>
					<select className="form-select" placeholder="State" value={this.state.selectedState} onChange={this.changeState}>
						<option>State</option>
						{this.state.states.map((e, key) => {
							return <option key={key}>{e.name}</option>;
						})}
					</select>
				</div>
				
				<div className="form-group">
					<label style={styles.lbl}>City</label>
					<select className="form-select" placeholder="City">
						<option>City</option>
						{this.state.cities.map((e, key) => {
							return <option key={key}>{e}</option>;
						})}
					</select>
				</div>
				<button type="submit" className="btn btn-success" style={styles.btn}>Submit</button>
				</div>
			</div>
		)
	}
}

export default App;

// Just some styles
const styles = {
  lbl: {
    marginTop: 5,
    marginBottom: 5,
  },  
  btn: {
    width:250,
	marginLeft:15,
	marginTop: 15,
  }
};

Friday, November 5, 2021

ReactJS Sign Up Form and Validation With Axios, PHP, Mysql, Formik, Yup and Bootstrap

ReactJS Sign Up Form and Validation With Axios, PHP, Mysql, Formik, Yup and Bootstrap

In this tutorial i will show how to create a form with validation using Formik and yup with bootstrap and PHP Mysql to save data form.

Formik : https://formik.org/
Yup : https://www.npmjs.com/package/yup
Bootstrap : https://react-bootstrap.github.io/getting-started/introduction/
Axios : https://github.com/axios/axios

Install Formik
npm install formik yup
C:\reactdev\myreactdev>npm install formik yup

https://github.com/axios/axios

Installing the Axios Client
$ npm install axios

C:\reactdev\myreactdev>npm install axios

Install bootstrap

npm install react-bootstrap bootstrap@5.1.3

C:\reactdev\myreactdev>npm install react-bootstrap bootstrap@5.1.3

https://react-bootstrap.github.io/getting-started/introduction/

CREATE TABLE `tbl_signup` (
  `id` int(11) NOT NULL,
  `firstName` varchar(150) NOT NULL,
  `lastName` varchar(150) NOT NULL,
  `email` varchar(150) NOT NULL,
  `password` varchar(150) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `tbl_signup`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `tbl_signup`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;


src/index.js
//src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css'

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
public/index.html
//public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>ReactJS </title>
  </head>
  <body>
    <div id="root"></div>
</body>
</html>
src/App.js
//src/App.js
import regimg from './assets/reg.jpg';
import { Signup } from './components/Signup';
import './App.css';

function App() {
  return (
    <div className="container mt-3">
      <div className="row">
        <div className="col-md-6 my-auto">
          <img className="img-fluid w-100" src={regimg} alt=""/>
        </div>
        <div className="col-md-6">
          <Signup />
        </div>
      </div>
    </div>
  );
}

export default App;
src/App.css
//src/App.css
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');

body {
  font-family: 'Roboto', sans-serif;
  }

label {
  font-size: 14px;
  padding-bottom: 10px;
}

input.form-control, input.form-control:focus {
  background: #F0F0FF;
}

.error {
  position: absolute;
  color: red;
  font-size: 11px;
}
src/components/Signup.js
//src/components/Signup.js
import React from 'react';
import { Formik, Form } from 'formik';
import { TextField } from './TextField';
import * as Yup from 'yup';
import axios from 'axios';

export const Signup = () => {
  const validate = Yup.object({
    firstName: Yup.string()
      .max(15, 'Must be 15 characters or less')
      .required('Required'),
    lastName: Yup.string()
      .max(20, 'Must be 20 characters or less')
      .required('Required'),
    email: Yup.string()
      .email('Email is invalid')
      .required('Email is required'),
    password: Yup.string()
      .min(6, 'Password must be at least 6 charaters')
      .required('Password is required'),
    confirmPassword: Yup.string()
      .oneOf([Yup.ref('password'), null], 'Password must match')
      .required('Confirm password is required'),
  })
  return (
    <Formik
      initialValues={{
        firstName: '',
        lastName: '',
        email: '',
        password: '',
        confirmPassword: ''
      }}
      validationSchema={validate}
      onSubmit={data => {
        console.log(data)
		
		let formData = new FormData();
        formData.append('firstName', data.firstName)
        formData.append('lastName', data.lastName)
        formData.append('email', data.email)
        formData.append('password', data.password)
 
        axios({
            method: 'post',
            url: 'http://localhost/devtest/reactjs/signup.php/',
            data: formData,
            config: { headers: {'Content-Type': 'multipart/form-data' }}
        })
        .then(function (response) {
            //handle success
            console.log(response)
            alert('New User Successfully Added.');  
        })
        .catch(function (response) {
            //handle error
            console.log(response)
        });
		
      }}>
	  
      {formik => (
        <div>
          <h1 className="my-4 font-weight-bold .display-4">Sign Up</h1>
          <Form>
            <TextField label="First Name" name="firstName" type="text" />
            <TextField label="last Name" name="lastName" type="text" />
            <TextField label="Email" name="email" type="email" />
            <TextField label="password" name="password" type="password" />
            <TextField label="Confirm Password" name="confirmPassword" type="password" />
            <button className="btn btn-primary mt-3" type="submit" style={{marginRight: 20}}>Register</button>
            <button className="btn btn-warning mt-3 ml-3" type="reset">Reset</button>
          </Form>
        </div>
      )}
    </Formik>
  )
}
src/components/TextField.js
//src/components/TextField.js
import React from 'react';
import { ErrorMessage, useField } from 'formik';

export const TextField = ({ label, ...props }) => {
  const [field, meta] = useField(props);
  return (
    <div className="mb-2">
      <label htmlFor={field.name}>{label}</label>
      <input
        className={`form-control shadow-none ${meta.touched && meta.error && 'is-invalid'}`}
        {...field} {...props}
        autoComplete="off"
      />
      <ErrorMessage component="div" name={field.name} className="error" />
    </div>
  )
}
http://localhost/devtest/reactjs/signup.php
//http://localhost/devtest/reactjs/signup.php
<?php
header("Access-Control-Allow-Origin: *"); //add this CORS header to enable any domain to send HTTP requests to these endpoints:
$host = "localhost"; 
$user = "root"; 
$password = ""; 
$dbname = "testingdb"; 

$con = mysqli_connect($host, $user, $password,$dbname);

$method = $_SERVER['REQUEST_METHOD'];

if (!$con) {
  die("Connection failed: " . mysqli_connect_error());
}

switch ($method) {
	case 'POST':	
		$firstName = $_POST["firstName"];
		$lastName = $_POST["lastName"];
		$email = $_POST["email"];
		$password = $_POST["password"];
		$sql = "insert into tbl_signup (firstName, lastName, email, password) values ('$firstName', '$lastName', '$email', '$password')"; 
	break;
}

// run SQL statement
$result = mysqli_query($con,$sql);

// die if SQL statement failed
if (!$result) {
  http_response_code(404);
  die(mysqli_error($con));
}

if ($method == 'POST') {
    echo json_encode($result);
} else {
    echo mysqli_affected_rows($con);
}

$con->close();

SwiftUI Travelling App Design

SwiftUI Travelling App Design

ContentView.swift
//
//  ContentView.swift
//  Swiftuitest
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    var body: some View {
        
        TabView{
            Home().tabItem {
                Image(systemName: "house").font(.title)
            }
            
            Text("activity").tabItem {
                Image(systemName: "person.fill.checkmark").font(.title)
            }
            
            Text("search").tabItem {
                Image(systemName: "magnifyingglass.circle").font(.title)
            }
            
            Text("person").tabItem {
                Image(systemName: "gear").font(.title)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Home.swift
//
//  Home.swift
//  Swiftuitest
//
//  Created by Cairocoders
//

import SwiftUI

struct Home : View {
    
    @State var selectedTab = Tabs.FirstTab
    
    var body : some View{
        
        VStack(alignment: .leading,spacing: 12){
            HStack{
                Button(action: {
                }) {
                    Image(systemName: "slider.horizontal.3")
                }
                
                Spacer()
                
                Button(action: {
                }) {
                    Image("photo1")
                        .resizable()
                        .frame(width: 40, height: 40)
                        .clipShape(Circle())
                }
            }
            
            Text("Find More").fontWeight(.heavy).font(.largeTitle).padding(.top,15)
            HStack{
                HStack {
                    
                    Text("Experiences").fontWeight(.heavy)
                        .foregroundColor(selectedTab == .FirstTab ? Color.red : Color.black)
                    .onTapGesture {
                        self.selectedTab = .FirstTab
                    }
                    
                    Spacer()
                    
                    Text("Adventures").fontWeight(.heavy)
                        .foregroundColor(selectedTab == .SecondTab ? Color.red : Color.black)
                    .onTapGesture {
                        self.selectedTab = .SecondTab
                    }
                    
                    Spacer()
                    
                    Text("Activities").fontWeight(.heavy)
                        .foregroundColor(selectedTab == .ThirdTab ? Color.red : Color.black)
                    .onTapGesture {
                        self.selectedTab = .ThirdTab
                    }
                }
                
                Spacer()
            }.padding([.top],30)
            .padding(.bottom, 15)
        
            if selectedTab == .FirstTab {
                FirstTabView()
            } else if selectedTab == .SecondTab {
                SecondTabView()
            } else {
                ThirdTabView()
            }
        }.padding()
    }
}

struct Home_Previews: PreviewProvider {
    static var previews: some View {
        Home()
    }
}

struct FirstTabView : View {
    var body : some View {
        ExperiencesTab()
        BottomView().padding(.top, 10)
    }
}

struct SecondTabView : View {
    var body : some View {
        AdventuresTab()
        BottomView().padding(.top, 10)
    }
}

struct ThirdTabView : View {
    var body : some View {
        ActivitiesTab()
        BottomView().padding(.top, 10)
    }
}

enum Tabs {
    case FirstTab
    case SecondTab
    case ThirdTab
}
BottomView.swift
//
//  BottomView.swift
//  Swiftuitest
//
//  Created by Cairocoders
//

import SwiftUI

struct BottomView : View {
      
      var body : some View{
          
          VStack{
              HStack{
                  Text("What you want ?").fontWeight(.heavy)
                  Spacer()
                  
                  Button(action: {
                  }) {
                      Text("View all").foregroundColor(.gray)
                  }
                  
              }.padding([.top], 15)
              
              ScrollView(.horizontal, showsIndicators: false) {
                  HStack(spacing: 35){
                      Button(action: {
                      }) {
                          VStack(spacing: 8){
                              Image("whatyouwant_01")
                                  .resizable().frame(width: 50, height: 50).cornerRadius(10)
                              Text("Hiking").foregroundColor(.gray)
                          }
                      }
                      
                      Button(action: {
                      }) {
                          VStack(spacing: 8){
                              Image("whatyouwant_02")
                                  .resizable().frame(width: 50, height: 50).cornerRadius(10)
                              Text("Ski").foregroundColor(.gray)
                          }
                      }
                          
                      Button(action: {
                              
                      }) {
                          VStack(spacing: 8){
                              Image("whatyouwant_03")
                                  .resizable().frame(width: 50, height: 50).cornerRadius(10)
                              Text("Sky Diving").foregroundColor(.gray)
                          }
                      }
                      Button(action: {
                              
                      }) {
                          VStack(spacing: 8){
                              Image("whatyouwant_04")
                                  .resizable().frame(width: 50, height: 50).cornerRadius(10)
                              Text("SkateBoard").foregroundColor(.gray)
                          }
                      }
                  }
              }.padding(.leading, 20)
              .padding([.top,.bottom], 15)
          }
      }
  }

struct BottomView_Previews: PreviewProvider {
    static var previews: some View {
        BottomView()
    }
}
//
//  Detail.swift
//  Swiftuitest
//
//  Created by Cairocoders on 11/4/21.
//

import SwiftUI

struct Detail : View {
    
    var travel : Travelling
    
    var body : some View{
        
        VStack{
            GeometryReader { geometry in
                Image(travel.image)
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    .frame(width: geometry.size.width, height: geometry.size.height)
                    .offset(y: geometry.frame(in: .global).minY/50)
                    .padding(.bottom, -200)
                    .edgesIgnoringSafeArea(.all)
            }
            GeometryReader{geo in
                ScrollView(.vertical, showsIndicators: true) {
                    
                    VStack(alignment: .leading){
                        
                        VStack(alignment: .leading, spacing: 10){
                            HStack{
                                VStack(alignment: .leading){
                                    Text(travel.name).fontWeight(.heavy).font(.largeTitle)
                                }
                                
                                Spacer()
                                Text("$587").foregroundColor(Color.orange).font(.largeTitle)
                            }
                        }.padding()
                        
                        VStack(alignment: .leading, spacing: 15){
                            HStack(spacing: 5){
                                Image(systemName: "mappin.and.ellipse").renderingMode(.original)
                                Text(travel.location).foregroundColor(Color.orange)
                            }
                            
                            HStack(spacing : 8){
                                ForEach(0..<travel.rating){_ in
                                    Image(systemName: "star.fill").font(.body).foregroundColor(.yellow)
                                }
                            }
                            
                            Text("People").fontWeight(.heavy)
                            Text("Number Of People In Your Group").foregroundColor(.gray)
                            HStack(spacing: 6){
                                ForEach(0..<5){i in
                                    Button(action: {
                                        
                                    }) {
                                        Text("\(i + 1)").foregroundColor(.white).padding(20)
                                    }.background(Color.orange)
                                    .cornerRadius(8)
                                }
                            }
                        }.padding(.horizontal,15)
                        
                       detailBottom()
                    }
                }
                
            }.background(Color.white)
            .clipShape(Rounded())
            .padding(.top, -75)
        }
    }
}

struct Detail_Previews: PreviewProvider {
    static var previews: some View {
        let travels =  Travelling(id: 1, name: "test", image: "details", rating: 1, location: "Olongapo")
        return Detail(travel: travels)
    
    }
}
detailBottom.swift
 
//
//  detailBottom.swift
//  Swiftuitest
//
//  Created by Cairocoders
//

import SwiftUI

struct detailBottom : View {
    
    var body : some View{
        
        VStack(alignment: .leading, spacing: 10){
            Text("Description").fontWeight(.heavy)
            Text("Towering redwoods, peaceful parkland and the magnificent coast are just some of the landscapes that make the Peninsula and South Bay extraordinary.").foregroundColor(.gray)
            
            HStack(spacing: 8){
                Button(action: {
                    
                }) {
                    Image(systemName: "bookmark")
                }
                
                Button(action: {
                    
                }) {
                    HStack(spacing: 6){
                        Text("Book Your Experience")
                        Image(systemName: "arrow.right.circle").renderingMode(.original)
                    }.foregroundColor(.white)
                    .padding()
                }.background(Color.orange)
                .cornerRadius(8)
            }.padding(.top, 6)
            
        }.padding()
    }
}

struct detailBottom_Previews: PreviewProvider {
    static var previews: some View {
        detailBottom()
    }
}
ExperiencesTab.swift
 
//
//  ExperiencesTab.swift
//  Swiftuitest
//
//  Created by Cairocoders
//

import SwiftUI

struct ExperiencesTab: View {
    
    @State var show = false
    @State var idSelected = 1
    @State var imageSelected = "fishing"
    @State var nameSelected = "Fishing Time"
    @State var locationSelected = "Olongapo City"
    @State var ratingSelected = 5
    var body : some View{
        
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 20){
                
                ForEach(data){i in
                    VStack(alignment: .leading,spacing: 12){
                        Button(action: {
                            self.show.toggle()
                            self.idSelected = i.id
                            self.imageSelected = i.image
                            self.nameSelected = i.name
                            self.locationSelected = i.location
                            self.ratingSelected = i.rating
                        }) {
                            Image(i.image)
                                .resizable().frame(width: 200, height: 300).cornerRadius(20)
                        }
                        Text(i.name).fontWeight(.heavy)
                        HStack(spacing: 5){
                            Image(systemName: "mappin.and.ellipse").renderingMode(.original)
                            Text(i.location).foregroundColor(.gray)
                        }
                    }
                }
            }
            .sheet(isPresented: $show) {
                Detail(travel: Travelling(id: self.idSelected, name: self.nameSelected, image: self.imageSelected, rating: self.ratingSelected, location: self.locationSelected))
            }
        }
    }
}

struct ExperiencesTab_Previews: PreviewProvider {
    static var previews: some View {
        ExperiencesTab()
    }
}
AdventuresTab.swift
 
//
//  AdventuresTab.swift
//  Swiftuitest
//
//  Created by Cairocoders
//

import SwiftUI

struct AdventuresTab: View {
    @State var show = false
    
    var body : some View{
        
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 20){
                VStack(alignment: .leading,spacing: 12){
                    Button(action: {
                        self.show.toggle()
                    }) {
                        Image("adventure1")
                            .resizable().frame(width: 200, height: 300).cornerRadius(20)
                    }
                    Text("Travel Time").fontWeight(.heavy)
                    HStack(spacing: 5){
                        Image(systemName: "mappin.and.ellipse").renderingMode(.original)
                        Text("Olongapo City").foregroundColor(.gray)
                    }
                }
                
                VStack(alignment: .leading,spacing: 12){
                    Button(action: {
                        self.show.toggle()
                    }) {
                        Image("adventure2")
                            .resizable().frame(width: 200, height: 300).cornerRadius(20)
                    }
                    Text("Family Camping").fontWeight(.heavy)
                    HStack(spacing: 5){
                        Image(systemName: "mappin.and.ellipse").renderingMode(.original)
                        Text("Subic Bay").foregroundColor(.gray)
                    }
                }
                
                VStack(alignment: .leading,spacing: 12){
                    Button(action: {
                        self.show.toggle()
                    }) {
                        Image("adventure3")
                            .resizable().frame(width: 200, height: 300).cornerRadius(20)
                    }
                    Text("Travelling").fontWeight(.heavy)
                    HStack(spacing: 5){
                        Image(systemName: "mappin.and.ellipse").renderingMode(.original)
                        Text("Clark").foregroundColor(.gray)
                    }
                }
            }
        }.sheet(isPresented: $show) {
            Detail(travel: Travelling(id: 1, name: "Fishing Time", image: "details", rating: 5, location: "Olongapo City"))
        }
    }
}

struct AdventuresTab_Previews: PreviewProvider {
    static var previews: some View {
        AdventuresTab()
    }
}
ActivitiesTab.swift
 
//
//  ActivitiesTab.swift
//  Swiftuitest
//
//  Created by Cairocoders
//

import SwiftUI

struct ActivitiesTab: View {
    @State var show = false
    
    var body : some View{
        
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 20){
                VStack(alignment: .leading,spacing: 12){
                    Button(action: {
                        self.show.toggle()
                    }) {
                        Image("travelling1")
                            .resizable().frame(width: 200, height: 300).cornerRadius(20)
                    }
                    Text("Wipe-clean").fontWeight(.heavy)
                    HStack(spacing: 5){
                        Image(systemName: "mappin.and.ellipse").renderingMode(.original)
                        Text("Olongapo City").foregroundColor(.gray)
                    }
                }
                
                VStack(alignment: .leading,spacing: 12){
                    Button(action: {
                        self.show.toggle()
                    }) {
                        Image("travelling2")
                            .resizable().frame(width: 200, height: 300).cornerRadius(20)
                    }
                    Text("Family Camping").fontWeight(.heavy)
                    HStack(spacing: 5){
                        Image(systemName: "mappin.and.ellipse").renderingMode(.original)
                        Text("Subic Bay").foregroundColor(.gray)
                    }
                }
                
                VStack(alignment: .leading,spacing: 12){
                    Button(action: {
                        self.show.toggle()
                    }) {
                        Image("travelling3")
                            .resizable().frame(width: 200, height: 300).cornerRadius(20)
                    }
                    Text("Travelling").fontWeight(.heavy)
                    HStack(spacing: 5){
                        Image(systemName: "mappin.and.ellipse").renderingMode(.original)
                        Text("Clark").foregroundColor(.gray)
                    }
                }
            }
        }.sheet(isPresented: $show) {
            Detail(travel: Travelling(id: 1, name: "Fishing Time", image: "details", rating: 5, location: "Olongapo City"))
        }
    }
}

struct ActivitiesTab_Previews: PreviewProvider {
    static var previews: some View {
        ActivitiesTab()
    }
}
Rounded.swift
 
//
//  Rounded.swift
//  Swiftuitest
//
//  Created by Cairocoders
//

import SwiftUI

struct Rounded : Shape {
    
    func path(in rect: CGRect) -> Path {
        
        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 40, height: 40))
        return Path(path.cgPath)
    }
}

struct Rounded_Previews: PreviewProvider {
    static var previews: some View {
        Rounded()
    }
}
Model.swift
 
//
//  Model.swift
//  Swiftuitest
//
//  Created by Cairocoders
//

import Foundation

struct Travelling : Identifiable {
    
    var id : Int
    var name : String
    var image : String
    var rating : Int
    var location : String
}

var data = [
    Travelling(id: 0, name: "Fishing Time", image: "fishing", rating: 2, location: "Olongapo City"),
    Travelling(id: 1, name: "Family Camping", image: "family_camping", rating: 5, location: "Subic Bay"),
    Travelling(id: 2, name: "Travelling", image: "traveling", rating: 3,location: "Clark")
]

Thursday, November 4, 2021

Vue.js Axios PHP How to upload multiple files

Vue.js Axios PHP How to upload multiple files

Download or Include 

axios
https://github.com/axios/axios

Using jsDelivr CDN: https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js

VueJS 
https://vuejs.org/v2/guide/installation.html

CDN : https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js

ploadfile.html
//uploadfile.html
<!doctype html>
<html>
<head>
<title>Vue.js Axios PHP How to upload multiple files</title>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
	<div class="container" id='myapp'>
		<br />
            <h3 align="center">Vue.js Axios PHP How to upload multiple files</h3>
        <br />
		<div class="panel panel-default">
			<div class="panel-heading"><b>Vue.js Axios PHP How to upload multiple files</b></div>
			<div class="panel-body">
				<div class="form-group">
                    <label>File Upload</label>
                    <input type="file" id="uploadfiles" ref="uploadfiles" multiple />
                </div>
                <div class="form-group">
                    <button type="button" @click='uploadFile()' class="btn btn-info" >Upload file</button>
                </div>
			<br>
			<div v-if="filenames.length" >
				<ul> 
					<li v-for= '(filename,index) in filenames' > 
						{{ filename }} 
					</li> 
				</ul>
			</div> 
			</div> 
		</div> 
	</div>
	<script>
		var app = new Vue({
			el: '#myapp',
			data: {
				file: "",
				filenames: []
			},
			methods: {
				uploadFile: function(){
					var el = this;

					let formData = new FormData();
						
					// Read selected files
					var files = this.$refs.uploadfiles.files;
					var totalfiles = this.$refs.uploadfiles.files.length;
    				for (var index = 0; index < totalfiles; index++) {
      					formData.append("files[]", files[index]);
    				}

					axios.post('upload.php', formData,
					{
						headers: {
						    'Content-Type': 'multipart/form-data'
						}
					})
					.then(function (response) {
						el.filenames = response.data;
							
						alert(el.filenames.length + " files is been uploaded.");
					})
					.catch(function (error) {
						console.log(error);
					}); 
						
				}
			}
		})
	</script>
</body>
</html>
upload.php
//upload.php
<?php
$files_arr = array();
if(isset($_FILES['files']['name'])){
	$countfiles = count($_FILES['files']['name']); // Count total files

	$upload_location = "uploads/"; // Upload directory

	// Loop all files
	for($index = 0;$index < $countfiles;$index++){

	   if(isset($_FILES['files']['name'][$index]) && $_FILES['files']['name'][$index] != ''){
	      	// File name
	      	$filename = $_FILES['files']['name'][$index];

	      	// Get extension
	      	$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));

	      	// Valid extensions
	      	$valid_ext = array("png","jpeg","jpg","pdf","txt","doc","docx");

	      	// Check extension
	      	if(in_array($ext, $valid_ext)){

	         	// File path
	         	$newfilename = time()."_".$filename;
	         	$path = $upload_location.$newfilename;

	         	// Upload file
	         	if(move_uploaded_file($_FILES['files']['tmp_name'][$index],$path)){
	            	$files_arr[] = $newfilename;
	         	}
	      	}
	   }
	}
}
echo json_encode($files_arr);
die;

Wednesday, November 3, 2021

SwiftUI Firebase Twitter Clone Design and Functionalities

SwiftUI Firebase Twitter Clone Design and Functionalities

https://github.com/firebase/firebase-ios-sdk.git
https://github.com/SDWebImage/SDWebImageSwiftUI.git

ContentView.swift
 
//
//  ContentView.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @State var show = false
    @State var showMenu = false
    
    var body: some View {
        
        let drag = DragGesture() //swipe to close menu
            .onEnded {
                if $0.translation.width < -100 {
                    withAnimation {
                        self.showMenu = false
                    }
                }
            }
        return NavigationView {
            //geometry property to adjust the frame of our Home View to fill the entire screen.
            GeometryReader { geometry in
                ZStack(alignment: .leading) {
                    TabView{
                        Home().tabItem {
                            Image(systemName: "house")
                        }.tag(0)
                        
                        Search().tabItem {
                            Image(systemName: "magnifyingglass.circle.fill")
                        }.tag(1)
                        
                        Text("Notifications").tabItem {
                            Image(systemName: "bell")
                        }.tag(2)
                        
                        Text("Messages").tabItem {
                            Image(systemName: "envelope")
                        }.tag(3)
                        
                    }.accentColor(.blue)
                    .edgesIgnoringSafeArea(.top)
                    
                    VStack{
                        Spacer()
                        HStack{
                            Spacer()
                            Button(action: {
                                self.show.toggle()
                            }) {
                                Image("addtwit").resizable().frame(width: 20, height: 20).padding()
                            }.background(Color("bg"))
                            .foregroundColor(.white)
                            .clipShape(Circle())
                        }.padding()
                    }.padding(.bottom,65)
                    
                    if self.showMenu {
                        MenuView()
                            .frame(width: geometry.size.width/1.5)
                            .transition(.move(edge: .leading)) //slide in transition
                    }
                    
                } //ZStack
                .sheet(isPresented: $show) {
                   CreateTweet(show: self.$show)
                }
                .gesture(drag) //swipe to the left the menu collapse
            }
            .navigationBarTitle(Text(""), displayMode: .inline)
            .navigationBarItems(leading:
                HStack {
                    Button(action: {
                        withAnimation {
                           self.showMenu.toggle()
                        }
                        print("Open the side menu")
                    }) {
                        Image("photo1").resizable().frame(width: 35, height: 35).clipShape(Circle())
                    }
                
                    Image("tweet")
                        .resizable()
                        .foregroundColor(.white)
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 60, height: 40, alignment: .center)
                    .padding(UIScreen.main.bounds.size.width/4+30)
                }
                ,trailing:
                HStack {
                    Button(action: {
                    }) {
                        Image(systemName: "sparkles")
                    }
                }
            )
        }// End Navigation
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Home.swift
//
//  Home.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import SDWebImageSwiftUI

struct Home: View {
    
    @ObservedObject var viewModel = TweetModel()
    
    var body : some View{
        ScrollView(.vertical, showsIndicators: false) {
            VStack(alignment: .leading){
                ForEach(viewModel.data){i in
                    
                    twitPost(name: i.name, id: i.tagId, pic: i.pic, image: i.url, msg: i.msg)
                    
                    if i.pic != ""{
                        AnimatedImage(url: URL(string: i.pic)!).resizable().frame(height: 300).cornerRadius(20).padding()
                    }
                    twitButton(like: i.likes, retwit: i.retwetts).offset(x: UIScreen.main.bounds.width / 4)
                }
            }
            
        }.padding(.bottom, 15)
    }
  }

struct Home_Previews: PreviewProvider {
    
    //@State static var showMenu = false
    
    static var previews: some View {
        //Home(showMenu: $showMenu)
        Home()
    }
}


struct twitPost : View {
  
  var name = ""
  var id = ""
  var pic = ""
  var image = ""
  var msg = ""
    
  var body : some View{
      
      HStack(alignment: .top){
          VStack{
              AnimatedImage(url: URL(string: image)!).resizable().frame(width: 50, height: 50).clipShape(Circle())

          }
          VStack(alignment: .leading){
              Text(name).fontWeight(.heavy)
              Text(id)
              Text(msg).padding(.top, 8)
          }
      }.padding()
  }
}

struct twitButton : View {
  
  var like = ""
  var retwit = ""
    
  var body : some View{
      
      HStack(spacing : 40){
          Button(action: {
              
          }) {
              Image(systemName: "message.and.waveform").resizable().frame(width: 20, height: 20)
              Text(like)
          }.foregroundColor(.gray)
          
          Button(action: {
              
          }) {
              Image(systemName: "crop.rotate").resizable().frame(width: 20, height: 20)
              Text(retwit)
          }.foregroundColor(.gray)
          
          Button(action: {
              
          }) {
              Image(systemName: "heart").resizable().frame(width: 20, height: 17)
          }.foregroundColor(.gray)
          
          Button(action: {
              
          }) {
              Image(systemName: "square.and.arrow.up").resizable().frame(width: 20, height: 20)
          }.foregroundColor(.gray)
      }
  }
}
Search.swift
//
//  Search.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI

struct Search: View {
    var body: some View {
        Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
    }
}

struct Search_Previews: PreviewProvider {
    static var previews: some View {
        Search()
    }
}
Datatypes.swift
//
//  Datatypes.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import Foundation

struct datatype : Identifiable {
  
  var id : String
  var name : String
  var msg : String
  var retwetts : String
  var likes : String
  var pic : String
  var url : String
  var tagId : String
}
TweetModel.swift
//
//  TweetModel.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import Foundation
import FirebaseFirestore

class TweetModel : ObservableObject{
  
  @Published var data = [datatype]()
    
    init() {
        
        let db = Firestore.firestore()
        
        db.collection("tweets").addSnapshotListener { (snap, err) in
            
            if err != nil{
                print((err?.localizedDescription)!)
                return
            }
            
            for i in snap!.documentChanges{
                
                if i.type == .added{
                    
                    print("hello world")
                    
                    let id = i.document.documentID
                    let name = i.document.get("name") as! String
                    let msg = i.document.get("msg") as! String
                    let pic = i.document.get("pic") as! String
                    let url = i.document.get("url") as! String
                    let retweets = i.document.get("retweet") as! String?
                    let likes = i.document.get("likes") as! String
                    let tagID = i.document.get("id") as! String?
                    
                    DispatchQueue.main.async {
                        self.data.append(datatype(id: id, name: name, msg: msg, retwetts: retweets ?? "0", likes: likes, pic: pic, url: url, tagId: tagID ?? "cairocoders"))
                    }
                }
            }// End ForEach
        } //End db.collection
    } //End init()
}

func postTweet(msg : String){
  
  let db = Firestore.firestore()
  
  db.collection("tweets").document().setData(["name" : "Cairocoders","id":"@cairocoders","msg":msg,"retweet":"0","likes":"0","pic":"","url":"https://images.pexels.com/photos/3981337/pexels-photo-3981337.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"]) { (err) in
      
      if err != nil{
          
          print((err?.localizedDescription)!)
          
          return
      }
      print("success")
  }
}
CreateTweet.swift
//
//  CreateTweet.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI

struct CreateTweet: View {
    
    @Binding var show : Bool
    @State var txt = ""
    
    var body : some View{
        VStack{
            HStack{
                Button(action: {
                    self.show.toggle()
                }) {
                    Text("Cancel")
                }
                
                Spacer()
                
                Button(action: {
                    postTweet(msg: self.txt)
                    self.show.toggle()
                }) {
                    Text("Tweet").padding()
                }.background(Color("bg"))
                .foregroundColor(.white)
                .clipShape(Capsule())
            }
            multilineTextField(txt: $txt)
        }.padding()
    }
  }
multilineTextField.swift
//
//  multilineTextField.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI

struct multilineTextField : UIViewRepresentable {
  
  
  @Binding var txt : String
  
  func makeCoordinator() -> multilineTextField.Coordinator {
      return multilineTextField.Coordinator(parent1 : self)
  }
  func makeUIView(context: UIViewRepresentableContext<multilineTextField>) -> UITextView {
      let text = UITextView()
      text.isEditable = true
      text.isUserInteractionEnabled = true
      text.text = "Type Something"
      text.textColor = .gray
      text.font = .systemFont(ofSize: 20)
      text.delegate = context.coordinator
      return text
  }
  
  func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext<multilineTextField>) {
      
  }
  
  class Coordinator : NSObject,UITextViewDelegate{
      var parent : multilineTextField
      init(parent1 : multilineTextField) {
          parent = parent1
      }
      func textViewDidBeginEditing(_ textView: UITextView) {
          textView.text = ""
          textView.textColor = .black
      }
      func textViewDidChange(_ textView: UITextView) {
          self.parent.txt = textView.text
      }
  }
}
MenuView.swift
//
//  MenuView.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI

struct MenuView: View {
    var body: some View {
        VStack(alignment: .leading) {
            HStack {
                VStack(alignment: .leading) {
                    Text("Cairocoders")
                        .foregroundColor(.black)
                    Text("@Cairocoders")
                        .foregroundColor(.black)
                    Text("239 Following 93 Followers")
                        .foregroundColor(.black)
                }
            }
            .padding(.top, 100)
            
            HStack {
                Image(systemName: "person")
                    .foregroundColor(.black)
                    .imageScale(.large)
                Text("Profile")
                    .foregroundColor(.black)
                    .font(.headline)
            }
            .padding(.top, 30)
             
            HStack {
                Image(systemName: "list.bullet.rectangle")
                    .foregroundColor(.black)
                    .imageScale(.large)
                Text("List")
                    .foregroundColor(.black)
                    .font(.headline)
            }
            .padding(.top, 30)
             
            HStack {
                Image(systemName: "message.and.waveform")
                    .foregroundColor(.black)
                    .imageScale(.large)
                Text("Topics")
                    .foregroundColor(.black)
                    .font(.headline)
            }
            .padding(.top, 30)
             
            HStack {
                Image(systemName: "bookmark")
                    .foregroundColor(.black)
                    .imageScale(.large)
                Text("Bookmarks")
                    .foregroundColor(.black)
                    .font(.headline)
            }
            .padding(.top, 30)
             
            Divider()
            
            HStack {
                Text("Setting and privacy")
                    .foregroundColor(.black)
                    .font(.headline)
            }
            .padding(.top, 30)
            
            HStack {
                Text("Help Center")
                    .foregroundColor(.black)
                    .font(.headline)
            }
            .padding(.top, 30)
            
            Spacer()
        }
        .padding()
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(Color("1"))
        .edgesIgnoringSafeArea(.all)
    }
}

struct MenuView_Previews: PreviewProvider {
    static var previews: some View {
        MenuView()
    }
}
DevSwiftUIApp.swift
//
//  DevSwiftUIApp.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import Firebase
 
@main
struct DevSwiftUIApp: App {
      
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
     
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
 
class AppDelegate: NSObject,UIApplicationDelegate{
       
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
           
        FirebaseApp.configure()
        return true
    }
}

Sunday, October 31, 2021

ReactJS Show Image Preview before Uploading

ReactJS Show Image Preview before Uploading

Install bootstrap

npm install react-bootstrap bootstrap@5.1.3

C:\reactdev\myreactdev>npm install react-bootstrap bootstrap@5.1.3

https://react-bootstrap.github.io/getting-started/introduction/

src/index.js
//src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css'

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
public/index.html
//public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>ReactJS </title>
  </head>
  <body>
    <div id="root"></div>
</body>
</html>
src/App.js src/App.js
//src/App.js
import { useState } from "react";

const App = () => {
	
	const [selectedImage, setSelectedImage] = useState();

	// This function will be triggered when the file field change
	const imageChange = (e) => {
		if (e.target.files && e.target.files.length > 0) {
		  setSelectedImage(e.target.files[0]);
		}
	};

    const onSubmit = (e) => {
        e.preventDefault() 
		alert(URL.createObjectURL(selectedImage))

    }
	
	// This function will be triggered when the "Remove This Image" button is clicked
	const removeSelectedImage = () => {
		setSelectedImage();
	};

  return (
    <>
      <div className="container" >
		<h1> ReactJS Show Image Preview before Uploading </h1>
		<div className="row">
			<form onSubmit={ onSubmit } className="form-inline">
                <div className="form-group">
                <label>Choose File to Upload: </label>
                <input type="file" className="form-control" onChange={imageChange} accept="image/*"/>
                </div> <br/>
                <button type="submit" className="btn btn-success" >Upload File</button>
            </form>

        {selectedImage && (
          <div style={styles.preview}>
            <img
              src={URL.createObjectURL(selectedImage)}
              style={styles.image}
              alt="Thumb"
            />
            <button onClick={removeSelectedImage} style={styles.delete}>
              Remove This Image
            </button>
          </div>
        )}
		</div>
      </div>
    </>
  );
};

export default App;

// Just some styles
const styles = {
  preview: {
    marginTop: 50,
    display: "flex",
    flexDirection: "column",
  },
  image: { maxWidth: "100%", maxHeight: 320 },
  delete: {
    cursor: "pointer",
    padding: 15,
    background: "red",
    color: "white",
    border: "none",
  },
};

ReactJS Get String Parameter - React Router Dom

ReactJS Get String Parameter - React Router Dom

src/index.js
//src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
public/index.html
//public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>ReactJS </title>
  </head>
  <body>
    <div id="root"></div>
</body>
</html>
src/App.js
//src/App.js
import {
  BrowserRouter as Router, Switch, Route, useLocation,
} from "react-router-dom"; //$npm install -save react-router-dom

const App = () => {
  return (
    <Router>
      <Switch>
        <Route path="/">
          <Home/>
        </Route>
      </Switch>
    </Router>
  );
};

const Home = (props) => {
  const location = useLocation(); //useLocation hook to get the location object that represents the current URL
  const search = location.search;
  console.log(search);

  const params = new URLSearchParams(search);
  console.log(params.get("s"));

  return (
    <div
      style={{
        display: "flex",
        alignItems: 'center',
        flexDirection: 'column',
        marginTop: 100,
      }}
    >
      <h3>ReactJS Get String Parameter - React Router Dom </h3>
      <h3>S: {params.get("s")}</h3>
      <h3>Page: {params.get("page")}</h3>
      <h3>Limit: {params.get("limit")}</h3>
      <h3>Order: {params.get("order")}</h3>
    </div>
  );
};

export default App;

ReactJS Ho to create Filter List

ReactJS Ho to create Filter List

src/index.js
//src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
public/index.html
//public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>ReactJS </title>
  </head>
  <body>
    <div id="root"></div>
</body>
</html>
src/App.js
//src/App.js
import React, { useState } from 'react';

import './App.css';

const COUNTRY = [
  { id: 1, name: 'AFGHANISTAN'},
  { id: 2, name: 'ANGOLA'},
  { id: 3, name: 'ARGENTINA'},
  { id: 4, name: 'ARMENIA'},
  { id: 5, name: 'BOLIVIA'},
  { id: 6, name: 'CAMBODIA'},
  { id: 7, name: 'PHILIPPINES'},
  { id: 9, name: 'UNITED ARAB EMIRATES'},
  { id: 10, name: 'UNITED KINGDOM'},
  { id: 11, name: 'UNITED STATES'},
];

function App() {
  const [name, setName] = useState('');
  const [foundCOUNTRY, setFoundCOUNTRY] = useState(COUNTRY);

  const filter = (e) => {
    const keyword = e.target.value;

    if (keyword !== '') {
      const results = COUNTRY.filter((country) => {
        return country.name.toLowerCase().startsWith(keyword.toLowerCase());
        // toLowerCase() method to make it case-insensitive
      });
      setFoundCOUNTRY(results);
    } else {
      setFoundCOUNTRY(COUNTRY); // If the text field is empty, show all COUNTRY
    }

    setName(keyword);
  };

  return (
    <div className="container">
      <input
        type="search"
        value={name}
        onChange={filter}
        className="input"
        placeholder="Filter"
      />

      <div className="country-list">
        {foundCOUNTRY && foundCOUNTRY.length > 0 ? (
          foundCOUNTRY.map((country) => (
            <li key={country.id} className="country">
              <span className="country-name">{country.name}</span>
            </li>
          ))
        ) : (
          <h1>No results found!</h1>
        )}
      </div>
    </div>
  );
}

export default App;
src/App.css
//src/App.css
.container {
  padding-top: 30px;
  width: 300px;
  margin: auto;
}

.input {
  padding: 5px 15px;
  width: 300px;
}

.country-list {
  margin-top: 30px;
}

.country {
  list-style: none;
  margin: 10px 0;
  padding: 10px;
  background: #eee;
  display: flex;
  justify-content: space-between;
}

.country-id {
  color: red;
  margin-right: 20px;
}

.country-name {
  color: blue;
}

Related Post