article

Thursday, June 24, 2021

SwiftUI Image background Onboarding Screen

SwiftUI Image background Onboarding Screen

In this tutorial we're going to create Image background onboarding Screen using GeometryReader and ZStack

ContentView.swift
 
//
//  ContentView.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @State private var showingSheet = false
    
    var body: some View {
        GeometryReader { geometry in
            ZStack {
                Image("bg2")
                    .resizable()
                    .aspectRatio(geometry.size, contentMode: .fill)
                    .edgesIgnoringSafeArea(.all)
                
                VStack {
                    Image("logo")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .foregroundColor(.white)
                        .padding(.bottom, 30)
                    
                    Text("Amazing Taste & Beautiful Place")
                        .font(.largeTitle)
                        .foregroundColor(.white)
                    Text("Discover the most amazing places in the world and share your experience Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..")
                        .foregroundColor(.white)
                        .frame(maxWidth: 320)
                        .padding(.top, 20)
                        .padding(.bottom, 50)
                    
                    Spacer()
                    
                    Rectangle()
                       .frame(height: 1)
                       .foregroundColor(.white)
                    
                    HStack {
                        Spacer()
                        Button("Login") {
                            showingSheet.toggle()
                        }
                        .font(.title3)
                        .foregroundColor(.white)
                        .padding(20)
                        
                        Spacer()
                        Button("Sign Up") {
                            showingSheet.toggle()
                        }
                        .font(.title3)
                        .foregroundColor(.white)
                        .padding(20)
                        
                        Spacer()
                   }
                   .sheet(isPresented: $showingSheet) {
                    LoginView()
                   }
               }//End VStack
                
            }// End ZStack
        }
    }// End body
}

struct LoginView: View {
    
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        Button("Press to dismiss") {
            presentationMode.wrappedValue.dismiss()
        }
        .font(.title)
        .padding()
        .background(Color.black)
    }
}

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

Sign Up Form Validation using jqBootstrapValidation using Python Flask Jquery Ajax and PostgreSQL

Sign Up Form Validation using jqBootstrapValidation using Python Flask Jquery Ajax and PostgreSQL

jqBootstrapValidation https://reactiveraven.github.io/jqBootstrapValidation/

A JQuery validation plugin for bootstrap forms.

CREATE TABLE users (
id serial PRIMARY KEY,
fullname VARCHAR ( 100 ) NOT NULL,
username VARCHAR ( 50 ) NOT NULL,
password VARCHAR ( 255 ) NOT NULL,
email VARCHAR ( 50 ) NOT NULL
);

install psycopg2 https://pypi.org/project/psycopg2/
Psycopg is the most popular PostgreSQL database adapter for the Python programming language.
(venv) PS C:\flaskmyproject> pip install psycopg2
app.py
 
#app.py
from flask import Flask, render_template, request, jsonify
from werkzeug.security import generate_password_hash, check_password_hash
import psycopg2 #pip install psycopg2 
import psycopg2.extras

app = Flask(__name__)

app.secret_key = "caircocoders-ednalan"

DB_HOST = "localhost"
DB_NAME = "sampledb"
DB_USER = "postgres"
DB_PASS = "admin"
    
conn = psycopg2.connect(dbname=DB_NAME, user=DB_USER, password=DB_PASS, host=DB_HOST) 

@app.route('/')
def index(): 
    return render_template('index.html')
 
@app.route("/insert",methods=["POST","GET"])
def insert():
    cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    if request.method == 'POST':
        fullname = request.form['fullname']
        username = request.form['username']
        email = request.form['email']
        password_hash = request.form['password']
        password = generate_password_hash(password_hash)
        cur.execute("INSERT INTO users (fullname, username, email, password) VALUES (%s,%s,%s,%s)",[fullname,username,email,password])
        conn.commit()       
        cur.close()
    return jsonify('New Records added successfully')
     
if __name__ == "__main__":
    app.run(debug=True)
templates/index.html
//templates/index.html
<!DOCTYPE html>
<html>
<head>
<title>Sign Up Form Validation using jqBootstrapValidation using Python Flask Jquery Ajax and PostgreSQL</title>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqBootstrapValidation/1.3.6/jqBootstrapValidation.js"></script>
<style>
.controls p{
    color:#a94442;
}
</style>
</head>
<body>
<div class="container">
    <h3 align="center">Sign Up Form Validation using jqBootstrapValidation using Python Flask Jquery Ajax and PostgreSQL</h3>
    <br />
    <div class="row">
        <div class="col-md-2"></div>
        <div class="col-md-6">
<form class="form-horizontal" method="POST" id="simple_form" novalidate="novalidate">
  <fieldset>
    <div id="legend">
      <legend class="">Register</legend>
    </div>

    <div class="control-group">
        <label class="control-label"  for="fullname">Name</label>
        <div class="controls">
          <input type="text" id="fullname" name="fullname" class="form-control form-control-lg" placeholder="Name" required="required" data-validation-required-message="Please enter your Name">
          <p class="text-danger help-block"></p>
        </div>
      </div>

    <div class="control-group">
      <label class="control-label"  for="username">Username</label>
      <div class="controls">
        <input type="text" id="username" name="username" class="form-control form-control-lg" placeholder="Name" required="required" data-validation-required-message="Please enter your Username">
        <p class="text-danger help-block"></p>
      </div>
    </div>
  
    <div class="control-group">
      <label class="control-label" for="email">E-mail</label>
      <div class="controls">
        <input type="email" id="email" name="email" class="form-control form-control-lg" placeholder="Email" required="required" data-validation-required-message="Please provide your E-mail">
        <p class="text-danger help-block"></p>
      </div>
    </div>
  
    <div class="control-group">
      <label class="control-label" for="password">Password</label>
      <div class="controls">
        <input type="password" id="password" name="password" class="form-control form-control-lg" placeholder="Password" required="required" data-validation-required-message="Please provide your password">
        <p class="text-danger help-block"></p>
      </div>
    </div>
  
    <div class="control-group">
      <label class="control-label"  for="password_confirm">Password (Confirm)</label>
      <div class="controls">
        <input type="password" id="password_confirm" class="form-control form-control-lg" name="password_confirm" placeholder="Password (Confirm)" required="required" data-validation-required-message="Please confirm password">
        <p class="text-danger help-block"></p>
      </div>
    </div>
  
    <div class="control-group">
        <div id="success"></div>
      <div class="controls">
        <button class="btn btn-success" type="submit" class="form-control form-control-lg" class="btn btn-primary" id="send_button">Register</button>
      </div>
    </div>
  </fieldset>
    </form>
    </div>
    <div class="col-md-2"></div>
</div>
</div>
<script>
$(document).ready(function(){
    $('#simple_form input').jqBootstrapValidation({
        preventSubmit: true,
        submitSuccess: function($form, event){     
            event.preventDefault();
            $this = $('#send_button');
            $this.prop('disabled', true);
            var form_data = $("#simple_form").serialize();
            $.ajax({
               url:"/insert",
               method:"POST",
               data:form_data,
               success:function(){
                $('#success').html("<div class='alert alert-success'><strong>Successfully Register. </strong></div>");
                $('#simple_form').trigger('reset');
               },
               error:function(){
                $('#success').html("<div class='alert alert-danger'>There is some error</div>");
                $('#simple_form').trigger('reset');
               },
               complete:function(){
                setTimeout(function(){
                 $this.prop("disabled", false);
                 $('#success').html('');
                }, 5000);
               }
            });
        },
    });
 
});
</script>
</body>
</html>

Load content Dynamically in Bootstrap Modal with Jquery AJAX and Python Flask PostgreSQL

Load content Dynamically in Bootstrap Modal with Jquery AJAX and Python Flask PostgreSQL

install psycopg2 https://pypi.org/project/psycopg2/
Psycopg is the most popular PostgreSQL database adapter for the Python programming language.
(venv) PS C:\flaskmyproject> pip install psycopg2

CREATE TABLE employee (
id serial PRIMARY KEY,
name VARCHAR ( 100 ) NOT NULL,
position VARCHAR ( 100 ) NOT NULL,
office VARCHAR ( 100 ) NOT NULL,
age INT NOT NULL,
salary INT NOT NULL,
photo VARCHAR ( 150 ) NOT NULL,
);


INSERT INTO
    employee(name, position, office, age, salary, photo)
VALUES
('Tiger Wood', 'Accountant', 'Tokyo', 36, 5689, '01.jpg'),
('Mark Oto Ednalan', 'Chief Executive Officer (CEO)', 'London', 56, 5648, '02.jpg'),
('Jacob thompson', 'Junior Technical Author', 'San Francisco', 23, 5689, '03.jpg'),
('cylde Ednalan', 'Software Engineer', 'Olongapo', 23, 54654, '04.jpg'),
('Rhona Davidson', 'Software Engineer', 'San Francisco', 26, 5465, '05.jpg'),
('Quinn Flynn', 'Integration Specialist', 'New York', 53, 56465, '06.jpg'),
('Tiger Nixon', 'Software Engineer', 'London', 45, 456, '07.jpg'),
('Airi Satou', 'Pre-Sales Support', 'New York', 25, 4568, '08.jpg'),
('Angelica Ramos', 'Sales Assistant', 'New York', 45, 456, '09.jpg'),
('Ashton updated', 'Senior Javascript Developer', 'Olongapo', 45, 54565, '01.jpg'),
('Bradley Greer', 'Regional Director', 'San Francisco', 27, 5485, '02.jpg'),
('Brenden Wagner', 'Javascript Developer', 'San Francisco', 38, 65468, '03.jpg'),
('Brielle Williamson', 'Personnel Lead', 'Olongapo', 56, 354685, '04.jpg'),
('Bruno Nash', 'Customer Support', 'New York', 36, 65465, '05.jpg'),
('cairocoders', 'Sales Assistant', 'Sydney', 45, 56465, '06.jpg'),
('Zorita Serrano', 'Support Engineer', 'San Francisco', 38, 6548, '07.jpg'),
('Zenaida Frank', 'Chief Operating Officer (COO)', 'San Francisco', 39, 545, '08.jpg'),
('Sakura Yamamoto', 'Support Engineer', 'Tokyo', 48, 5468, '05.jpg'),
('Serge Baldwin', 'Data Coordinator', 'Singapore', 85, 5646, '05.jpg'),
('Shad Decker', 'Regional Director', 'Tokyo', 45, 4545, '05.jpg');
app.py
 
#app.py
from flask import Flask, render_template, request, jsonify
import psycopg2 #pip install psycopg2 
import psycopg2.extras

app = Flask(__name__)

app.secret_key = "caircocoders-ednalan"

DB_HOST = "localhost"
DB_NAME = "sampledb"
DB_USER = "postgres"
DB_PASS = "admin"
    
conn = psycopg2.connect(dbname=DB_NAME, user=DB_USER, password=DB_PASS, host=DB_HOST)  

@app.route('/')
def index():
    cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    cur.execute("SELECT * FROM employee ORDER BY id ASC")
    employee = cur.fetchall()  
    return render_template('index.html', employee = employee)
 
@app.route("/ajaxfile",methods=["POST","GET"])
def ajaxfile():
    cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    if request.method == 'POST':
        userid = request.form['userid']
        print(userid)
        cur.execute("SELECT * FROM employee WHERE id = %s", [userid])
        employeelist = cur.fetchall() 
    return jsonify({'htmlresponse': render_template('response.html',employeelist=employeelist)})
 
if __name__ == "__main__":
    app.run(debug=True)
templates/index.html
//templates/index.html
<!DOCTYPE html>
<html>
<head>
<title>Load content Dynamically in Bootstrap Modal with Jquery AJAX and Python Flask PostgreSQL</title>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body >
<div class="container">
   <br />
   <h3 align="center">Load content Dynamically in Bootstrap Modal with Jquery AJAX and Python Flask PostgreSQL</h3>
   <div class="row">
    <div class="col-md-12">
        <div class="panel-body">
            <div class="table-responsive">
                <table class="table table-bordered">
                    <thead>
                        <tr>
                            <th width="60">Photo</th>
                            <th>Name</th>
                            <th>Position</th>
                            <th>Office</th>
                            <th>Age</th>
                            <th>Salary</th>
                            <th>View</th>
                        </tr>
                        </thead> 
                        {% for row in employee %}
                            <tr>
                                <td><img src="/static/images/{{row.photo}}" height="50" width="50"/></td>
                                <td>{{row.name}}</td>
                                <td>{{row.position}}</td>
                                <td>{{row.office}}</td>
                                <td>{{row.age}}</td>
                                <td>{{row.salary}}</td>
                                <td><button data-id='{{row.id}}' class="userinfo btn btn-success">Info</button></td>
                            </tr>
                        {% endfor %}
                </table>
            </div>
        </div>    
    </div>    
    </div>
</div>    
            <script type='text/javascript'>
            $(document).ready(function(){
                $('.userinfo').click(function(){
                    var userid = $(this).data('id');
                    $.ajax({
                        url: '/ajaxfile',
                        type: 'post',
                        data: {userid: userid},
                        success: function(data){ 
                            $('.modal-body').html(data); 
                            $('.modal-body').append(data.htmlresponse);
                            $('#empModal').modal('show'); 
                        }
                    });
                });
            });
            </script>
        </div>
        <div class="modal fade" id="empModal" role="dialog">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h4 class="modal-title">User Info</h4>
                          <button type="button" class="close" data-dismiss="modal">×</button>
                        </div>
                        <div class="modal-body">
                        </div>
                        <div class="modal-footer">
                          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                        </div>
                    </div>
                </div>
        </div>
    </body>
</html>
templates/response.html
//templates/response.html
{% for row in employeelist %} 
<table border='0' width='100%'>
    <tr>
        <td width="300"><img src="/static/images/{{row.photo}}">
        <td style="padding:20px;">
        <p>Name : {{row.name}}</p>
        <p>Position : {{row.position}}</p>
        <p>Office : {{row.office}}</p>
        <p>Age : {{row.age}}</p>
        <p>Salary : {{row.salary}}</p>
        </td>
    </tr>
</table>
{% endfor %}

Wednesday, June 23, 2021

SwiftUI fullscreen image background using GeometryReader and ZStack

SwiftUI fullscreen image background using GeometryReader and ZStack ContentView.swift
 
//
//  ContentView.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @State var progressValue: Float = 0.0
    
    var body: some View {
        GeometryReader { geometry in
            ZStack {
                Image("bg")
                    .resizable()
                    .aspectRatio(geometry.size, contentMode: .fill)
                    .edgesIgnoringSafeArea(.all)

                VStack(spacing: 25){
                    
                    Image("trophy")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 250, height: 250)
                    
                    Text("Well Done !!!")
                        .font(.title)
                        .fontWeight(.heavy)
                        .foregroundColor(.black)
                    
                    // Score And Back To Home Button...
                    
                    HStack(spacing: 15){
                        
                        Image(systemName: "checkmark")
                            .font(.largeTitle)
                            .foregroundColor(.green)
                        
                        Text("23")
                            .font(.largeTitle)
                            .foregroundColor(.black)
                        
                        Image(systemName: "xmark")
                            .font(.largeTitle)
                            .foregroundColor(.red)
                            .padding(.leading)
                        
                        Text("12")
                            .font(.largeTitle)
                            .foregroundColor(.black)
                    }
                    
                    Button(action: {
                    }, label: {
                        HStack {
                            Image(systemName: "house.circle")
                                .font(.largeTitle)
                            Text("Goto Home")
                                .fontWeight(.heavy)
                                .foregroundColor(.white)
                                .padding(.vertical)
                                .frame(width: UIScreen.main.bounds.width - 150)
                        }
                        .background(Color.blue)
                        .foregroundColor(.white)
                        .cornerRadius(15)
                    })
                }
            }
        }
    }
}


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

SwiftUI Circular Progress Bar using Stacks and Circle Shapes

SwiftUI Circular Progress Bar using Stacks and Circle Shapes ContentView.swift
 
//
//  ContentView.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @State var progressValue: Float = 0.0
    
    var body: some View {
        ZStack {
            Color.gray
                .opacity(0.1)
                .edgesIgnoringSafeArea(.all)
            
            VStack {
                ProgressBar(progress: self.$progressValue)
                    .frame(width: 200, height: 200)
                    .padding(40)
                
                Button(action: {
                    self.incrementProgress()
                }) {
                    HStack {
                        Image(systemName: "plus.rectangle.fill")
                        Text("Increment")
                    }
                    .padding(15.0)
                    .overlay(
                        RoundedRectangle(cornerRadius: 15.0)
                            .stroke(lineWidth: 2.0)
                    )
                }
                
                Spacer()
            }
        }
    }
    
    func incrementProgress() {
        let randomValue = Float([0.010, 0.020, 0.030, 0.040, 0.50].randomElement()!)
        self.progressValue += randomValue
    }
}

struct ProgressBar: View {

    @Binding var progress: Float
    
    var body: some View {
        ZStack {
            Circle()
                .stroke(lineWidth: 30)
                .opacity(0.6)
                .foregroundColor(Color.blue)
            
            Circle()
                .trim(from: 0.0, to: CGFloat(min(self.progress, 1.0)))
                .stroke(style: StrokeStyle(lineWidth: 30, lineCap: .round, lineJoin: .round))
                .foregroundColor(Color.green)
                .rotationEffect(Angle(degrees: 270.0))
                .animation(.linear)
            
            Text(String(format: "%.0f %%", min(self.progress, 1.0)*100.0))
                .font(.largeTitle)
                .bold()
        }
    }
}

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

REST API Query Parameter GET Request using Python Flask and PostgreSQL Database

REST API Query Parameter GET Request using Python Flask and PostgreSQL Database

Create table

CREATE TABLE useraccount (
id serial PRIMARY KEY,
username VARCHAR ( 100 ) NOT NULL,
password VARCHAR ( 100 ) NOT NULL
);

Insert data

INSERT INTO useraccount (username, password) VALUES ('tutorial101', 'pbkdf2:sha256:150000$KxxiGerN$4c37a656baa0034035a6be2cd698b5da8b036ae63eef3ab0b08b9c18b9765648');

Testing Rest API

REST API Testing is open-source web automation testing technique that is used for testing RESTful APIs for web applications. The purpose of rest api testing is to record the response of rest api by sending various HTTP/S requests to check if rest api is working fine or not. Rest api testing is done by GET, POST, PUT and DELETE methods.

Rest stands for Representational State Transfer. It is an architectural style and an approach for communication used in the development of Web Services. REST has become a logical choice for building APIs. It enables users to connect and interact with cloud services efficiently.

An API or Application Programming Interface is a set of programming instructions for accessing a web-based software application.

API is a set of commands used by an individual program to communicate with one another directly and use each other's functions to get information.

Install the Advanced Rest Client
1. Go to Google Chrome's Web Store
2. Search for "Advanced Rest Client" https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo and Install the extension

install psycopg2 https://pypi.org/project/psycopg2/
Psycopg is the most popular PostgreSQL database adapter for the Python programming language.
(venv) PS C:\flaskmyproject> pip install psycopg2

app.py
 
#app.py
from flask import Flask, jsonify, request
from werkzeug.security import generate_password_hash, check_password_hash

import psycopg2 #pip install psycopg2 
import psycopg2.extras

app = Flask(__name__)

DB_HOST = "localhost"
DB_NAME = "sampledb"
DB_USER = "postgres"
DB_PASS = "admin"
    
conn = psycopg2.connect(dbname=DB_NAME, user=DB_USER, password=DB_PASS, host=DB_HOST)  

@app.route('/')
def home():
    passhash = generate_password_hash('cairocoders')
    print(passhash)
    return passhash

@app.route('/user') 
def get_user():
    try:
        id = request.args.get('id')
        if id:
            cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
            cursor.execute("SELECT * FROM useraccount WHERE id=%s", id)
            row = cursor.fetchone()
            resp = jsonify(row)
            resp.status_code = 200
            return resp
        else:
            resp = jsonify('User "id" not found in query string')
            resp.status_code = 500
            return resp
    except Exception as e:
        print(e)
    finally:
        cursor.close() 
        conn.close()

if __name__ == "__main__":
    app.run()

REST API Login Logout Using Python Flask and PostgreSQL Database

REST API Login Logout Using Python Flask and PostgreSQL Database

Create table

CREATE TABLE useraccount (
id serial PRIMARY KEY,
username VARCHAR ( 100 ) NOT NULL,
password VARCHAR ( 100 ) NOT NULL
);

Insert data

INSERT INTO useraccount (username, password) VALUES ('tutorial101', 'pbkdf2:sha256:150000$KxxiGerN$4c37a656baa0034035a6be2cd698b5da8b036ae63eef3ab0b08b9c18b9765648');

{"username":"tutorial101","password":"cairocoders"}

Username : tutorial101
password : cairocoders

Testing Rest API

REST API Testing is open-source web automation testing technique that is used for testing RESTful APIs for web applications. The purpose of rest api testing is to record the response of rest api by sending various HTTP/S requests to check if rest api is working fine or not. Rest api testing is done by GET, POST, PUT and DELETE methods.

Rest stands for Representational State Transfer. It is an architectural style and an approach for communication used in the development of Web Services. REST has become a logical choice for building APIs. It enables users to connect and interact with cloud services efficiently.

An API or Application Programming Interface is a set of programming instructions for accessing a web-based software application.

API is a set of commands used by an individual program to communicate with one another directly and use each other's functions to get information.

Install the Advanced Rest Client
1. Go to Google Chrome's Web Store
2. Search for "Advanced Rest Client" https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo and Install the extension

 
#app.py
from flask import Flask, jsonify, request, session
from werkzeug.security import generate_password_hash, check_password_hash
from flask_cors import CORS #pip install -U flask-cors
from datetime import timedelta

import psycopg2 #pip install psycopg2 
import psycopg2.extras

app = Flask(__name__)
 
app.config['SECRET_KEY'] = 'cairocoders-ednalan'
 
app.config['PERMANENT_SESSION_LIFETIME'] =  timedelta(minutes=10)
CORS(app) 

DB_HOST = "localhost"
DB_NAME = "sampledb"
DB_USER = "postgres"
DB_PASS = "admin"
    
conn = psycopg2.connect(dbname=DB_NAME, user=DB_USER, password=DB_PASS, host=DB_HOST)  

@app.route('/')
def home():
    passhash = generate_password_hash('cairocoders')
    print(passhash)
    if 'username' in session:
        username = session['username']
        return jsonify({'message' : 'You are already logged in', 'username' : username})
    else:
        resp = jsonify({'message' : 'Unauthorized'})
        resp.status_code = 401
        return resp
 
@app.route('/login', methods=['POST'])
def login():
    _json = request.json
    _username = _json['username']
    _password = _json['password']
    print(_password)
    # validate the received values
    if _username and _password:
        #check user exists          
        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
         
        sql = "SELECT * FROM useraccount WHERE username=%s"
        sql_where = (_username,)
         
        cursor.execute(sql, sql_where)
        row = cursor.fetchone()
        username = row['username']
        password = row['password']
        if row:
            if check_password_hash(password, _password):
                session['username'] = username
                cursor.close()
                return jsonify({'message' : 'You are logged in successfully'})
            else:
                resp = jsonify({'message' : 'Bad Request - invalid password'})
                resp.status_code = 400
                return resp
    else:
        resp = jsonify({'message' : 'Bad Request - invalid credendtials'})
        resp.status_code = 400
        return resp
         
@app.route('/logout')
def logout():
    if 'username' in session:
        session.pop('username', None)
    return jsonify({'message' : 'You successfully logged out'})
         
if __name__ == "__main__":
    app.run()

Monday, June 21, 2021

Generate PDF Report using Python Flask PostgreSQL

Generate PDF Report using Python Flask PostgreSQL

install psycopg2 https://pypi.org/project/psycopg2/
Psycopg is the most popular PostgreSQL database adapter for the Python programming language.
(venv) PS C:\flaskmyproject> pip install psycopg2

CREATE TABLE employee (
id serial PRIMARY KEY,
name VARCHAR ( 100 ) NOT NULL,
position VARCHAR ( 100 ) NOT NULL,
office VARCHAR ( 100 ) NOT NULL,
age INT NOT NULL,
salary INT NOT NULL,
photo VARCHAR ( 150 ) NOT NULL,
);


INSERT INTO
    employee(name, position, office, age, salary, photo)
VALUES
('Tiger Wood', 'Accountant', 'Tokyo', 36, 5689, '01.jpg'),
('Mark Oto Ednalan', 'Chief Executive Officer (CEO)', 'London', 56, 5648, '02.jpg'),
('Jacob thompson', 'Junior Technical Author', 'San Francisco', 23, 5689, '03.jpg'),
('cylde Ednalan', 'Software Engineer', 'Olongapo', 23, 54654, '04.jpg'),
('Rhona Davidson', 'Software Engineer', 'San Francisco', 26, 5465, '05.jpg'),
('Quinn Flynn', 'Integration Specialist', 'New York', 53, 56465, '06.jpg'),
('Tiger Nixon', 'Software Engineer', 'London', 45, 456, '07.jpg'),
('Airi Satou', 'Pre-Sales Support', 'New York', 25, 4568, '08.jpg'),
('Angelica Ramos', 'Sales Assistant', 'New York', 45, 456, '09.jpg'),
('Ashton updated', 'Senior Javascript Developer', 'Olongapo', 45, 54565, '01.jpg'),
('Bradley Greer', 'Regional Director', 'San Francisco', 27, 5485, '02.jpg'),
('Brenden Wagner', 'Javascript Developer', 'San Francisco', 38, 65468, '03.jpg'),
('Brielle Williamson', 'Personnel Lead', 'Olongapo', 56, 354685, '04.jpg'),
('Bruno Nash', 'Customer Support', 'New York', 36, 65465, '05.jpg'),
('cairocoders', 'Sales Assistant', 'Sydney', 45, 56465, '06.jpg'),
('Zorita Serrano', 'Support Engineer', 'San Francisco', 38, 6548, '07.jpg'),
('Zenaida Frank', 'Chief Operating Officer (COO)', 'San Francisco', 39, 545, '08.jpg'),
('Sakura Yamamoto', 'Support Engineer', 'Tokyo', 48, 5468, '05.jpg'),
('Serge Baldwin', 'Data Coordinator', 'Singapore', 85, 5646, '05.jpg'),
('Shad Decker', 'Regional Director', 'Tokyo', 45, 4545, '05.jpg');
app.py
 
#app.py
from flask import Flask, render_template, url_for, Response
from fpdf import FPDF #pip install fpdf 

import psycopg2 #pip install psycopg2 
import psycopg2.extras

app = Flask(__name__)   

DB_HOST = "localhost"
DB_NAME = "sampledb"
DB_USER = "postgres"
DB_PASS = "admin"
    
conn = psycopg2.connect(dbname=DB_NAME, user=DB_USER, password=DB_PASS, host=DB_HOST)

@app.route('/')
def home():
    return render_template('index.html')
 
@app.route('/download/report/pdf')
def download_report():
    try:
        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
         
        cursor.execute("SELECT * FROM employee")
        result = cursor.fetchall()
 
        pdf = FPDF()
        pdf.add_page()
         
        page_width = pdf.w - 2 * pdf.l_margin
         
        pdf.set_font('Times','B',14.0) 
        pdf.cell(page_width, 0.0, 'Employee Data', align='C')
        pdf.ln(10)
 
        pdf.set_font('Courier', '', 12)
         
        col_width = page_width/4
         
        pdf.ln(1)
         
        th = pdf.font_size
         
        for row in result:
            pdf.cell(col_width, th, str(row['id']), border=1)
            pdf.cell(col_width, th, row['name'], border=1)
            pdf.cell(col_width, th, row['position'], border=1)
            pdf.cell(col_width, th, row['office'], border=1)
            pdf.ln(th)
         
        pdf.ln(10)
         
        pdf.set_font('Times','',10.0) 
        pdf.cell(page_width, 0.0, '- end of report -', align='C')
         
        return Response(pdf.output(dest='S').encode('latin-1'), mimetype='application/pdf', headers={'Content-Disposition':'attachment;filename=employee_report.pdf'})
    except Exception as e:
        print(e)
    finally:
        cursor.close() 
        conn.close()
         
 
if __name__ == "__main__":
    app.run()
templates/index.html
//templates/index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Generate PDF Report using Python Flask PostgreSQL</title>
</head>
<body>
    <div style="margin: 10px 0 0 10px;width: 600px">
    <h2>Generate PDF Report using Python Flask PostgreSQL</h2>
<p>
    <a href="{{ url_for('.download_report') }}">Generate Pdf Report</a>
</p>
    </div>
</body>
</html>

SwiftUI Blog Post Screen Stretchy header with parallax scrolling effect

SwiftUI Blog Post Screen Stretchy header with parallax scrolling effect ContentView.swift
 
//
//  ContentView.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    let articleContent =

    """
    Ang Bayan ng El Nido ay isang bayan at marine reserve park sa lalawigan ng Palawan, Pilipinas. Ito ay may 420 kilometrong layo sa timog-kanluran ng Maynila. Ayon sa senso ng 2015, ito ay may populasyon na 41,606 sa may 9,465 na kabahayan. 85% ng mga tao dito ay naninirahan sa mga bukirin, samantalang 15% na nalalabi ay makikita sa Población (town proper).

    Ang bayan ay makikita sa pinakahilagang dulo ng pulo ng Palawan. Ito ay binubuo ng 45 na mga pulo na may iba't ibang itsura at porma. Katulad ng kabuuang Palawan, ang El Nido ay kabilang sa Eurasian Plate, isang plate na hiwalay sa Philippine Plate na siyang kinabibilangan ng kabuuang bansa. Ang mga limestone cliffs na matatagpuan dito ay katulad ng mga matatagpuan sa Ha Long Bay sa Vietnam, Krabi sa Tailanda at Guillin sa Tsina na bahagi rin ng Eurasian Plate.
    """
    
    var body: some View {
        ScrollView {
            
            GeometryReader { geometry in // Implement Parallax Scrolling Header
                VStack {
                    if geometry.frame(in: .global).minY <= 0 {
                        Image("banner")
                            .resizable()
                            .aspectRatio(contentMode: .fill)
                            .frame(width: geometry.size.width, height: geometry.size.height)
                            .offset(y: geometry.frame(in: .global).minY/9)
                            .clipped()
                    } else {
                        Image("banner")
                            .resizable()
                            .aspectRatio(contentMode: .fill)
                            .frame(width: geometry.size.width, height: geometry.size.height + geometry.frame(in: .global).minY)
                            .clipped()
                            .offset(y: -geometry.frame(in: .global).minY)
                    }
                }
            }
            .frame(height: 400)
            
            VStack(alignment: .leading) {
                HStack {
                    Image("photo1")
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(width: 60, height: 60)
                        .clipped()
                        .cornerRadius(10)
                    VStack(alignment: .leading) {
                        Text("Article by")
                            .font(.title3)
                            .foregroundColor(.gray)
                        Text("Cairocoders")
                            .font(.title3)
                    }
                }
                .padding(.top, 20)
                
                Text("El Nido Palawan")
                    .font(.largeTitle)
                    .lineLimit(nil)
                    .padding(.top, 10)
                Text("23 min read • 22. July 2020")
                    .font(.title3)
                    .foregroundColor(.gray)
                    .padding(.top, 10)
                Text(articleContent)
                    .font(.title2)
                    .lineLimit(nil)
                    .padding(.top, 30)
                
            }//End VStack
            .frame(width: 350)
        }
        .edgesIgnoringSafeArea(.top)
    }
}


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

Upload and display image using Python Flask and insert to PostgreSQL

Upload and display image using Python Flask and insert to PostgreSQL

install psycopg2 https://pypi.org/project/psycopg2/
Psycopg is the most popular PostgreSQL database adapter for the Python programming language.
(venv) PS C:\flaskmyproject> pip install psycopg2

CREATE TABLE upload (
id serial PRIMARY KEY,
title VARCHAR ( 100 ) NOT NULL,
);
app.py
 
#app.py
from flask import Flask, flash, request, redirect, url_for, render_template
import urllib.request
import os
from werkzeug.utils import secure_filename
 
import psycopg2 #pip install psycopg2 
import psycopg2.extras
    
app = Flask(__name__)
    
app.secret_key = "cairocoders-ednalan"
    
DB_HOST = "localhost"
DB_NAME = "sampledb"
DB_USER = "postgres"
DB_PASS = "admin"
    
conn = psycopg2.connect(dbname=DB_NAME, user=DB_USER, password=DB_PASS, host=DB_HOST)
 
UPLOAD_FOLDER = 'static/uploads/'
 
app.secret_key = "secret key"
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
 
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
 
def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
     
 
@app.route('/')
def home():
    return render_template('index.html')
 
@app.route('/', methods=['POST'])
def upload_image():
    cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    if 'file' not in request.files:
        flash('No file part')
        return redirect(request.url)
    file = request.files['file']
    if file.filename == '':
        flash('No image selected for uploading')
        return redirect(request.url)
    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)
        file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        #print('upload_image filename: ' + filename)

        cursor.execute("INSERT INTO upload (title) VALUES (%s)", (filename,))
        conn.commit()

        flash('Image successfully uploaded and displayed below')
        return render_template('index.html', filename=filename)
    else:
        flash('Allowed image types are - png, jpg, jpeg, gif')
        return redirect(request.url)
 
@app.route('/display/<filename>')
def display_image(filename):
    #print('display_image filename: ' + filename)
    return redirect(url_for('static', filename='uploads/' + filename), code=301)
 
if __name__ == "__main__":
    app.run()
templates/index.html
//templates/index.html
<html>
<head>
<title>Upload and display image using Python Flask and insert to PostgreSQL</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />        
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</head>
<body>
<p><h1 align="center">Upload and display image using Python Flask and insert to PostgreSQL</h1></p>
<div class="container">
<div class="row">
    <h2>Select a file to upload</h2>
    <p>
        {% with messages = get_flashed_messages() %}
          {% if messages %}
            <ul>
            {% for message in messages %}
              <li>{{ message }}</li>
            {% endfor %}
            </ul>
          {% endif %}
        {% endwith %}
    </p>
    {% if filename %}
        <div>
            <img src="{{ url_for('display_image', filename=filename) }}">
        </div>
    {% endif %}
    <form method="post" action="/" enctype="multipart/form-data">
        <dl>
            <p>
                <input type="file" name="file" class="form-control" autocomplete="off" required>
            </p>
        </dl>
        <p>
            <input type="submit" value="Submit" class="btn btn-info">
        </p>
    </form>
</div>
</div>
</body>
</html>

Thursday, June 17, 2021

SwiftUI How to Fetch Json data and display it into a list and show details view

SwiftUI How to Fetch Json data and display it into a list and show details view

Goto to the https://jsonplaceholder.typicode.com/users we use this JSON URL to display the data

ContentView.swift
//
//  ContentView.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @State var users: [User] = []
    
    var body: some View {
        NavigationView {
            List(users) { user in
                NavigationLink(destination: DetailsView(userItem: user)) {
                       HStack {
                         Text(user.name)
                           .font(.headline)
                       }.padding(7)
                    }
               }
            .navigationBarTitle("Fetch JSON data")
            .onAppear {
                apiCall().getUsers { (users) in
                self.users = users
                }
            }
        }
    }
}


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

import SwiftUI

struct DetailsView: View {
    let userItem: User
    
    var body: some View {
        VStack(alignment: .leading) {
            VStack {
                Text(userItem.name)
                    .font(.title2)
                    .multilineTextAlignment(.leading)
                
                Text("Username: \(userItem.username)")
                    .font(.title2)
                    .multilineTextAlignment(.leading)
                
                Text("Email: \(userItem.email)")
                    .font(.title2)
                    .multilineTextAlignment(.leading)
            }
            Spacer()
        }
        .padding()
        .navigationBarTitle(Text(userItem.name), displayMode: .automatic)
    }
}
ViewModel.swift
//
//  ViewModel.swift
//  Test
//
//  Created by Cairocoders
//

import Foundation

class apiCall {
    func getUsers(completion:@escaping ([User]) -> ()) {
        guard let url = URL(string: "https://jsonplaceholder.typicode.com/users") else { return }
        URLSession.shared.dataTask(with: url) { (data, _, _) in
            let users = try! JSONDecoder().decode([User].self, from: data!)
            //print(users)
            
            DispatchQueue.main.async {
                completion(users)
            }
        }
        .resume()
    }
}
Model.swift
//
//  Model.swift
//  Test
//
//  Created by Cairocoders
//

import Foundation
struct User: Codable, Identifiable {
    let id: String = UUID().uuidString

    let username: String
    let name: String
    let email: String
    
    private enum CodingKeys: String, CodingKey {
        case id
        case name
        case username
        case email
    }
}

SwiftUI How to Create List and NavigationLink with DetailsView

SwiftUI How to Create List and NavigationLink with DetailsView ContentView.swift
 
//
//  ContentView.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    var body: some View {
        NavigationView {
               List(countryList) { countryItem in
                    NavigationLink(destination: DetailsView(countryItem: countryItem)) {
                       HStack {
                         ZStack {
                           Text(countryItem.flag)
                             .font(.largeTitle)
                             .frame(width: 50, height: 50)
                         }
                         Text(countryItem.name)
                           .font(.headline)
                       }.padding(7)
                    }
               }
            .navigationBarTitle("Countries")
        }
    }
}


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

import SwiftUI

struct DetailsView: View {
    let countryItem: Country
    
    var body: some View {
        VStack(alignment: .leading) {
            HStack {
                ZStack {
                    Text(countryItem.flag)
                      .font(.largeTitle)
                      .frame(width: 50, height: 50)
                      .padding(.trailing, 5)
                }
                Text("🏢 \(countryItem.capital)")
                    .font(.largeTitle)
                    .bold()
                Spacer()
            }
            Spacer()
        }
        .padding()
        .navigationBarTitle(Text(countryItem.name), displayMode: .automatic)
    }
}
Model.swift
 
//
//  Model.swift
//  Test
//
//  Created by Cairocoders
//

import Foundation

struct Country: Identifiable {
    let id = UUID()
    let flag: String
    let name: String
    let capital: String
}
//let flags: [String: String] = [
//  "AD": "🇦🇩", "AE": "🇦🇪", "AF": "🇦🇫", "AG": "🇦🇬", "AI": "🇦🇮", "AL": "🇦🇱", "AM": "🇦🇲", "AO": "🇦🇴", "AQ": "🇦🇶", "AR": "🇦🇷", "AS": "🇦🇸", "AT": "🇦🇹", "AU": "🇦🇺", "AW": "🇦🇼", "AX": "🇦🇽", "AZ": "🇦🇿", "BA": "🇧🇦", "BB": "🇧🇧", "BD": "🇧🇩", "BE": "🇧🇪", "BF": "🇧🇫", "BG": "🇧🇬", "BH": "🇧🇭", "BI": "🇧🇮", "BJ": "🇧🇯", "BL": "🇧🇱", "BM": "🇧🇲", "BN": "🇧🇳", "BO": "🇧🇴", "BQ": "🇧🇶", "BR": "🇧🇷", "BS": "🇧🇸", "BT": "🇧🇹", "BV": "🇧🇻", "BW": "🇧🇼", "BY": "🇧🇾", "BZ": "🇧🇿", "CA": "🇨🇦", "CC": "🇨🇨", "CD": "🇨🇩", "CF": "🇨🇫", "CG": "🇨🇬", "CH": "🇨🇭", "CI": "🇨🇮", "CK": "🇨🇰", "CL": "🇨🇱", "CM": "🇨🇲", "CN": "🇨🇳", "CO": "🇨🇴", "CR": "🇨🇷", "CU": "🇨🇺", "CV": "🇨🇻", "CW": "🇨🇼", "CX": "🇨🇽", "CY": "🇨🇾", "CZ": "🇨🇿", "DE": "🇩🇪", "DJ": "🇩🇯", "DK": "🇩🇰", "DM": "🇩🇲", "DO": "🇩🇴", "DZ": "🇩🇿", "EC": "🇪🇨", "EE": "🇪🇪", "EG": "🇪🇬", "EH": "🇪🇭", "ER": "🇪🇷", "ES": "🇪🇸", "ET": "🇪🇹", "FI": "🇫🇮", "FJ": "🇫🇯", "FK": "🇫🇰", "FM": "🇫🇲", "FO": "🇫🇴", "FR": "🇫🇷", "GA": "🇬🇦", "GB": "🇬🇧", "GD": "🇬🇩", "GE": "🇬🇪", "GF": "🇬🇫", "GG": "🇬🇬", "GH": "🇬🇭", "GI": "🇬🇮", "GL": "🇬🇱", "GM": "🇬🇲", "GN": "🇬🇳", "GP": "🇬🇵", "GQ": "🇬🇶", "GR": "🇬🇷", "GS": "🇬🇸", "GT": "🇬🇹", "GU": "🇬🇺", "GW": "🇬🇼", "GY": "🇬🇾", "HK": "🇭🇰", "HM": "🇭🇲", "HN": "🇭🇳", "HR": "🇭🇷", "HT": "🇭🇹", "HU": "🇭🇺", "ID": "🇮🇩", "IE": "🇮🇪", "IL": "🇮🇱", "IM": "🇮🇲", "IN": "🇮🇳", "IO": "🇮🇴", "IQ": "🇮🇶", "IR": "🇮🇷", "IS": "🇮🇸", "IT": "🇮🇹", "JE": "🇯🇪", "JM": "🇯🇲", "JO": "🇯🇴", "JP": "🇯🇵", "KE": "🇰🇪", "KG": "🇰🇬", "KH": "🇰🇭", "KI": "🇰🇮", "KM": "🇰🇲", "KN": "🇰🇳", "KP": "🇰🇵", "KR": "🇰🇷", "KW": "🇰🇼", "KY": "🇰🇾", "KZ": "🇰🇿", "LA": "🇱🇦", "LB": "🇱🇧", "LC": "🇱🇨", "LI": "🇱🇮", "LK": "🇱🇰", "LR": "🇱🇷", "LS": "🇱🇸", "LT": "🇱🇹", "LU": "🇱🇺", "LV": "🇱🇻", "LY": "🇱🇾", "MA": "🇲🇦", "MC": "🇲🇨", "MD": "🇲🇩", "ME": "🇲🇪", "MF": "🇲🇫", "MG": "🇲🇬", "MH": "🇲🇭", "MK": "🇲🇰", "ML": "🇲🇱", "MM": "🇲🇲", "MN": "🇲🇳", "MO": "🇲🇴", "MP": "🇲🇵", "MQ": "🇲🇶", "MR": "🇲🇷", "MS": "🇲🇸", "MT": "🇲🇹", "MU": "🇲🇺", "MV": "🇲🇻", "MW": "🇲🇼", "MX": "🇲🇽", "MY": "🇲🇾", "MZ": "🇲🇿", "NA": "🇳🇦", "NC": "🇳🇨", "NE": "🇳🇪", "NF": "🇳🇫", "NG": "🇳🇬", "NI": "🇳🇮", "NL": "🇳🇱", "NO": "🇳🇴", "NP": "🇳🇵", "NR": "🇳🇷", "NU": "🇳🇺", "NZ": "🇳🇿", "OM": "🇴🇲", "PA": "🇵🇦", "PE": "🇵🇪", "PF": "🇵🇫", "PG": "🇵🇬", "PH": "🇵🇭", "PK": "🇵🇰", "PL": "🇵🇱", "PM": "🇵🇲", "PN": "🇵🇳", "PR": "🇵🇷", "PS": "🇵🇸", "PT": "🇵🇹", "PW": "🇵🇼", "PY": "🇵🇾", "QA": "🇶🇦", "RE": "🇷🇪", "RO": "🇷🇴", "RS": "🇷🇸", "RU": "🇷🇺", "RW": "🇷🇼", "SA": "🇸🇦", "SB": "🇸🇧", "SC": "🇸🇨", "SD": "🇸🇩", "SE": "🇸🇪", "SG": "🇸🇬", "SH": "🇸🇭", "SI": "🇸🇮", "SJ": "🇸🇯", "SK": "🇸🇰", "SL": "🇸🇱", "SM": "🇸🇲", "SN": "🇸🇳", "SO": "🇸🇴", "SR": "🇸🇷", "SS": "🇸🇸", "ST": "🇸🇹", "SV": "🇸🇻", "SX": "🇸🇽", "SY": "🇸🇾", "SZ": "🇸🇿", "TC": "🇹🇨", "TD": "🇹🇩", "TF": "🇹🇫", "TG": "🇹🇬", "TH": "🇹🇭", "TJ": "🇹🇯", "TK": "🇹🇰", "TL": "🇹🇱", "TM": "🇹🇲", "TN": "🇹🇳", "TO": "🇹🇴", "TR": "🇹🇷", "TT": "🇹🇹", "TV": "🇹🇻", "TW": "🇹🇼", "TZ": "🇹🇿", "UA": "🇺🇦", "UG": "🇺🇬", "UM": "🇺🇲", "US": "🇺🇸", "UY": "🇺🇾", "UZ": "🇺🇿", "VA": "🇻🇦", "VC": "🇻🇨", "VE": "🇻🇪", "VG": "🇻🇬", "VI": "🇻🇮", "VN": "🇻🇳", "VU": "🇻🇺", "WF": "🇼🇫", "WS": "🇼🇸", "YE": "🇾🇪", "YT": "🇾🇹", "ZA": "🇿🇦", "ZM": "🇿🇲", "ZW": "🇿🇼"
//]
let countryList: [Country] = [
    Country(
        flag: "🇵🇭",
        name: "Philippines",
        capital: "Manila"),
    Country(
        flag: "🇫🇷",
        name: "France",
        capital: "Paris"),
    Country(
        flag: "🇮🇪",
        name: "Ireland",
        capital: "Dublin"),
    Country(
        flag: "🇲🇽",
        name: "Mexico",
        capital: "Mexico City"),
    Country(
        flag: "🇨🇦",
        name: "Canada",
        capital: "Ottawa"),
    Country(
        flag: "🇺🇸",
        name: "United States",
        capital: "Whashington D.C"),
    Country(
        flag: "🇰🇾",
        name: "Australia",
        capital: "Canberra"),
    Country(
        flag: "🇨🇳",
        name: "China",
        capital: "Beijing"),
    Country(
        flag: "🇬🇧",
        name: "United Kingdom",
        capital: "London")
]

SwiftUI How to Implement a TabView with TabItem

SwiftUI How to Implement a TabView with TabItem ContentView.swift
 
//
//  ContentView.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    var body: some View {
        
        TabView {
                 FirstView()
                     .tabItem {
                         Label("Search", systemImage: "magnifyingglass")
                     }
                 SecondView()
                     .tabItem {
                         Label("Home", systemImage: "house")
                     }
                 ThirdView()
                     .tabItem {
                         Label("Profile", systemImage: "person")
                     }
             }

    } // End Body
}


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

import SwiftUI

struct FirstView: View {
    var body: some View {
        Text("FirstView")
    }
}

struct FirstView_Previews: PreviewProvider {
    static var previews: some View {
        FirstView()
    }
}
SecondView.swift
 
//
//  SecondView.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct SecondView: View {
    var body: some View {
        Text("SecondView")
    }
}

struct SecondView_Previews: PreviewProvider {
    static var previews: some View {
        SecondView()
    }
}
ThirdView.swift
 
//
//  ThirdView.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct ThirdView: View {
    var body: some View {
        Text("ThirdView")
    }
}

struct ThirdView_Previews: PreviewProvider {
    static var previews: some View {
        ThirdView()
    }
}

Tuesday, June 15, 2021

SwiftUI How to delete rows from a list

SwiftUI How to delete rows from a list

SwiftUI makes it easy to let users swipe to delete rows by attaching an onDelete(perform:) handler to some or all of your data.

ContentView.swift
 
//
//  ContentView.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    @State private var users = ["Airi Satou", "Angelica Ramos", "Ashton Cox", "Bradley Greer", "Brenden Wagner", "Brielle Williamson"]

    var body: some View {
        NavigationView {
            List {
                ForEach(users, id: \.self) { user in
                    Text(user)
                }
                .onDelete(perform: delete)
            }
        }
    }

    func delete(at offsets: IndexSet) {
        users.remove(atOffsets: offsets)
    }
}

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

import SwiftUI

struct ContentView: View {
    
    @State private var newTodo = ""
    private let todosKey = "todosKey"
    @State private var allTodos: [TodoItem] = []
    
    var body: some View {
        NavigationView {
          VStack { //vertical stack
               
              HStack { //Horizontal Stack
              TextField("Add todo...", text: $newTodo)
                .textFieldStyle(RoundedBorderTextFieldStyle())
               
              Button(action: {
                guard !self.newTodo.isEmpty else { return }
                self.allTodos.append(TodoItem(todo: self.newTodo))
                self.newTodo = ""
                self.saveTodos()
              }) {
                  Image(systemName: "plus")
              }
              .padding(.leading, 5)
            }.padding() //end horizontal stack
   
            List { //List view to display all of the to-dos in our allTodos
              ForEach(allTodos) { todoItem in
                Text(todoItem.todo)
              }.onDelete(perform: deleteTodo)
            }.onAppear(perform: loadTodos)
            
          }//end vertical stack
          .navigationBarTitle("Todos")
        }
   }
    
    //Storing To-dos in UserDefaults
    //UserDefaults is a database where you store key-value
    //https://developer.apple.com/documentation/foundation/userdefaults
    
    private func saveTodos() {
      UserDefaults.standard.set(try? PropertyListEncoder().encode(self.allTodos), forKey: todosKey)
    }
    
    private func loadTodos() {
      if let todosData = UserDefaults.standard.value(forKey: todosKey) as? Data {
        if let todosList = try? PropertyListDecoder().decode(Array<TodoItem>.self, from: todosData) {
          self.allTodos = todosList
        }
      }
    }
    
    private func deleteTodo(at offsets: IndexSet) {
      self.allTodos.remove(atOffsets: offsets)
      saveTodos()
    }
    
}

//Add codable to make Sure each item encoded and decoded
struct TodoItem: Codable, Identifiable { //Identifiable protocol this ensures that the system can distinguish one TodoItem from another
    var id = UUID()
  let todo: String
}

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

Monday, June 14, 2021

SwiftUI Firebase List and Add

SwiftUI Firebase List and Add ContentView.swift
 
//
//  ContentView.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @State private var name: String = ""
    @ObservedObject private var viewModel = ContactViewModel()
    
    var body: some View {
        
        NavigationView {
            VStack { //vertical stack
                HStack { //Horizontal Stack
                    TextField("Add New...", text: $name)
                      .textFieldStyle(RoundedBorderTextFieldStyle())
                      .font(.title)
                    Button(action: {
                        self.viewModel.addData(name: name)
                        print("button tapped!")
                    }) {
                        Image(systemName: "plus")
                            .padding()
                            .foregroundColor(.white)
                            .background(Color.blue)
                            .cornerRadius(40)
                    }
                    .padding(.leading, 5)
                }.padding() //end horizontal stack
                
                List(viewModel.contacts) { contact in
                    VStack(alignment: .leading) {
                        Text(contact.name).font(.title)
                    }
                }.onAppear() {
                    self.viewModel.fetchData()
                }
            }
            .navigationTitle("Contact List")
        }
    }// End body
}


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

import Foundation
import SwiftUI
struct Contact: Codable, Identifiable {
    var id: String = UUID().uuidString
    var name: String
}
ContactViewModel.swift
 
//
//  ContactViewModel.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import Foundation
import FirebaseFirestore
import SwiftUI

class ContactViewModel: ObservableObject {
    
    @Published var contacts = [Contact]()

    private var db = Firestore.firestore()
    
    func fetchData() {
        db.collection("contacts").addSnapshotListener { (querySnapshot, error) in
            guard let documents = querySnapshot?.documents else {
                print("No documents")
                return
            }
            
            self.contacts = documents.map { (queryDocumentSnapshot) -> Contact in
                let data = queryDocumentSnapshot.data()
                let name = data["name"] as? String ?? ""
                return Contact(name: name)
            }
        }
    }
    
    func addData(name: String) {
        db.collection("contacts").addDocument(data: ["name": name])
    }
}
DevSwiftUIApp.swift
 
//
//  DevSwiftUIApp.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import Firebase

@main
struct DevSwiftUIApp: App {
    
    init() {
    FirebaseApp.configure()
    }
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

Friday, June 11, 2021

SwiftUI Side Menu

SwiftUI Side Menu

In this tutorial we will create a side menu with a smooth slide-out animation

ContentView.swift
 
//
//  ContentView.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @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) {
                    Home(showMenu: self.$showMenu)
                        .frame(width: geometry.size.width, height: geometry.size.height)
                        .offset(x: self.showMenu ? geometry.size.width/2 : 0)
                        .disabled(self.showMenu ? true : false)
                    if self.showMenu {
                        MenuView()
                            .frame(width: geometry.size.width/2)
                            .transition(.move(edge: .leading)) //slide in transition
                    }
                }
                .gesture(drag) //swipe to the left the menu collapse
            }
            .navigationBarTitle("Side Menu", displayMode: .inline)
            .navigationBarItems(leading: (
                Button(action: {
                    withAnimation {
                        self.showMenu.toggle()
                    }
                }) {
                    Image(systemName: "line.horizontal.3")
                        .imageScale(.large)
                }
            ))
        }// End Navigation
    }
}

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

struct Home: View {
    
    @Binding var showMenu: Bool
    
    var body: some View {
        Button(action: {
            withAnimation {
               self.showMenu = true
            }
            print("Open the side menu")
        }) {
            Text("Show Menu")
                .padding()
                .background(Color.green)
                .foregroundColor(Color.white)
                .font(.title)
        }
    }
}
MenuView.swift
 
//
//  MenuView.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct MenuView: View {
    var body: some View {
        VStack(alignment: .leading) {
            HStack {
                Image(systemName: "person")
                    .foregroundColor(.white)
                    .imageScale(.large)
                Text("Profile")
                    .foregroundColor(.white)
                    .font(.headline)
            }
            .padding(.top, 100)
            
            HStack {
                Image(systemName: "envelope")
                    .foregroundColor(.white)
                    .imageScale(.large)
                Text("Messages")
                    .foregroundColor(.white)
                    .font(.headline)
            }
            .padding(.top, 30)
            
            HStack {
                Image(systemName: "gear")
                    .foregroundColor(.white)
                    .imageScale(.large)
                Text("Settings")
                    .foregroundColor(.white)
                    .font(.headline)
            }
            .padding(.top, 30)
            
            HStack {
                Image(systemName: "figure.walk")
                    .foregroundColor(.white)
                    .imageScale(.large)
                Text("Logout")
                    .foregroundColor(.white)
                    .font(.headline)
            }
            .padding(.top, 30)
            
            Spacer()
        }
        .padding()
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(Color.gray)
        .edgesIgnoringSafeArea(.all)
    }
}

struct MenuView_Previews: PreviewProvider {
    static var previews: some View {
        MenuView()
    }
}

SwiftUI full screen modal using fullScreenCover

SwiftUI full screen modal using fullScreenCover

SwiftUI’s fullScreenCover() modifier gives us a presentation style for times when you want to cover as much of the screen as possible, and in code it works almost identically to regular sheets.

ContentView.swift
 
//
//  ContentView.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    @State private var isPresented = false

    var body: some View {
        Button("Present!") {
            isPresented.toggle()
        }
        .fullScreenCover(isPresented: $isPresented, content: FullScreenModalView.init)
    }
}

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

struct FullScreenModalView: View {

    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        Text("modal view")
        
        Button("Dismiss Modal") {
            presentationMode.wrappedValue.dismiss()
        }
    }
}

SwiftUI Recipe App Using Carousel List and Grid with Details View

SwiftUI Recipe App Using Carousel List and Grid with Details View 

In this tutorial I'm going to show how to create a recipe app with carousel list and grid

ContentView.swift
 
//
//  ContentView.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    var body: some View {
        
        Home()
    }
}

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

struct Home : View {
    
    @State var search = ""
    @State var index = 0
    @State var columns = Array(repeating: GridItem(.flexible(), spacing: 15), count: 2)
    
    var body: some View{

        ScrollView(.vertical, showsIndicators: false) {
            
            LazyVStack{
                
                HStack{
                    
                    Text("Recipes")
                        .font(.title)
                        .fontWeight(.bold)
                    
                    Spacer()
                }
                .padding(.horizontal)
                
                TextField("Search", text: self.$search)
                    .padding(.vertical,10)
                    .padding(.horizontal)
                    .background(Color.black.opacity(0.07))
                    .cornerRadius(10)
                    .padding(.horizontal)
                    .padding(.top,25)
                
                // Carousel List...
                
                TabView(selection: self.$index){
                    
                    ForEach(1...5,id: \.self) {index in
                        Image("banner\(index)")
                            .resizable()
                            // adding animation...
                            .frame(height: self.index == index ?  230 : 180)
                            .cornerRadius(15)
                            .padding(.horizontal)
                            // for identifying current index....
                            .tag(index)
                    }
                }
                .frame(height: 230)
                .padding(.top,25)
                .tabViewStyle(PageTabViewStyle())
                .animation(.easeOut)
                
                // adding custom Grid....
                
                HStack{
                    
                    Text("Popular")
                        .font(.title)
                        .fontWeight(.bold)
                    
                    Spacer()
                    
                    Button {
                        
                        // reducing to row.....
                        
                        withAnimation(.easeOut){
                            
                            if self.columns.count == 2{
                                
                                self.columns.removeLast()
                            }
                            else{
                                
                                self.columns.append(GridItem(.flexible(), spacing: 15))
                            }
                        }
                        
                    } label: {
                    
                        Image(systemName: self.columns.count == 2 ? "rectangle.grid.1x2" : "square.grid.2x2")
                            .font(.system(size: 24))
                            .foregroundColor(.black)
                    }

                }
                .padding(.horizontal)
                .padding(.top,25)
                
                LazyVGrid(columns: self.columns,spacing: 25){
                    
                    ForEach(data){recipe in
                        
                        // GridView....
                        
                        PopularRecipes(recipes: recipe,columns: self.$columns, setid: recipe.id) //PopularRecipes.swift
                    }
                }
                .padding([.horizontal,.top])
                
            }
            .padding(.vertical)
        }
        .background(Color.black.opacity(0.05).edgesIgnoringSafeArea(.all))
    }
}
Recipes.swift
 
//
//  Recipes.swift
//  Test
//
//  Created by Cairocoders 
//

import Foundation

struct Recipe : Identifiable {
    
    var id : Int
    var name : String
    var image : String
    var rating : Int
    var details : String
}

var data = [

    Recipe(id: 0, name: "Bistek Tagalog", image: "recipe1", rating: 2, details: "A dish made of strips of salted and peppered sirloin beef, usually flattened with a meat tenderizing tool, slowly cooked in soy sauce, calamansi juice, garlic and onions, a specialty of the Tagalog region"),
    Recipe(id: 1, name: "Boogie flight", image: "recipe2", rating: 5, details: "A boodle fight is a meal that dispenses with cutlery and dishes. Diners instead practice kamayan, Filipino for eating with the hands"),
    Recipe(id: 2, name: "Sinigang Na Baboy", image: "recipe3", rating: 3,details: "Sinigang na baboy with Gabi is a Filipino pork soup with taro cooked in a sour broth."),
    Recipe(id: 3, name: "Ginisang Togue", image: "recipe4", rating: 2,details: "Ginisang Togue is basically Sauteed Mung Bean Sprout with carrots, bell pepper, shrimp, and tofu."),
    Recipe(id: 4, name: "Ginisang Munggo (Monggo)", image: "recipe5", rating: 4, details: "Munggo or Mung bean (or even green bean to some) is a seed of Vigna radiata, a plant native to India and Pakistan. Since the plant originated in Asia, it was easy to spread along the nearby countries. This seed became a hit when it reached the Philippines."),
    Recipe(id: 5, name: "Pork Estofado (Sweet Pork Stew)", image: "recipe6", rating: 2, details: "Pork Estofado with saba bananas, carrots, Chinese sausage, and a sweet and savory sauce. Perfect with steamed rice!"),
    Recipe(id: 6, name: "Pata Tim", image: "recipe7", rating: 4, details: "Brimming in a pork stew infused with aromatic peppercorn, sesame oil and soy sauce, Pata Tim is a classic Filipino dish with traces in Chinese cuisine"),
    Recipe(id: 7, name: "Pancit Palabok", image: "recipe8", rating: 3, details: "Pancit Palabok is a noodle dish with shrimp sauce and topped with several ingredients such as cooked shrimp, boiled pork, crushed chicharon, tinapa flakes, fried tofu, scallions, and fried garlic. "),
]
PopularRecipes.swift
 
//
//  PopularRecipes.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct PopularRecipes: View {
    
    var recipes : Recipe
    @Binding var columns : [GridItem]
    @Namespace var namespace
    
    @State var showAlert: Bool = false
    @State var msg: String = ""
    
    @State var show = false
    @State var setid: Int
    
    var body: some View{
         
 
        VStack{
             
            if self.columns.count == 2{
                 
                VStack(spacing: 15){
                     
                    ZStack(alignment: Alignment(horizontal: .trailing, vertical: .top)) {
                         
                        Image(recipes.image)
                            .resizable()
                            .frame(height: 250)
                            .cornerRadius(15)
                        
                        Button {
                            self.showAlert = true
                            self.msg = "\(recipes.name) Done Heart..."
                        } label: {
                         
                            Image(systemName: "heart.fill")
                                .foregroundColor(.red)
                                .padding(.all,10)
                                .background(Color.white)
                                .clipShape(Circle())
                        }
                        .padding(.all,10)
 
                    }
                    .matchedGeometryEffect(id: "image", in: self.namespace)
                     
                    Text(recipes.name)
                        .fontWeight(.bold)
                        .lineLimit(1)
                        .matchedGeometryEffect(id: "title", in: self.namespace)
 
                    Button {
                        setid = (recipes.id)
                        show.toggle()
                    } label: {
                     
                        Text("Learn More")
                            .foregroundColor(.white)
                            .padding(.vertical,10)
                            .padding(.horizontal,25)
                            .background(Color.green)
                            .cornerRadius(5)
                    }
                    .matchedGeometryEffect(id: "learnmore", in: self.namespace)
                    
                }//End VStack
                .alert(isPresented: $showAlert, content: {
                    Alert(title: Text(self.msg))
                })
                
                .sheet(isPresented: $show, content: {
                    Details(setid: setid, data: recipes)
                })
            }
            else{
                 
                // Row View....
                 
                // adding animation...
                 
                HStack(spacing: 15){
                     
                    ZStack(alignment: Alignment(horizontal: .trailing, vertical: .top)) {
                         
                        Image(recipes.image)
                            .resizable()
                            .frame(width: (UIScreen.main.bounds.width - 45) / 2,height: 250)
                            .cornerRadius(15)
                         
                        Button {
                            self.showAlert = true
                            self.msg = "\(recipes.name) Done Heart..."
                        } label: {
                         
                            Image(systemName: "heart.fill")
                                .foregroundColor(.red)
                                .padding(.all,10)
                                .background(Color.white)
                                .clipShape(Circle())
                        }
                        .padding(.all,10)
 
                    }
                    .matchedGeometryEffect(id: "image", in: self.namespace)
                    .alert(isPresented: $showAlert, content: {
                        Alert(title: Text(self.msg))
                    })
                    
                    VStack(alignment: .leading, spacing: 10) {
                         
                        Text(recipes.name)
                            .fontWeight(.bold)
                            .matchedGeometryEffect(id: "title", in: self.namespace)
                         
                        // Rating Bar...
                         
                        HStack(spacing: 10){
                             
                            ForEach(1...5,id: \.self) {rating in
                                Image(systemName: "star.fill")
                                    .foregroundColor(self.recipes.rating >= rating ? .yellow : .gray)
                            }
                             
                            Spacer(minLength: 0)
                        }
                         
                        Button {
                            setid = (recipes.id)
                            show.toggle()
                        } label: {
                         
                            Text("Learn More")
                                .foregroundColor(.white)
                                .padding(.vertical,10)
                                .padding(.horizontal,25)
                                .background(Color.green)
                                .cornerRadius(5)
                        }
                        .matchedGeometryEffect(id: "learnmore", in: self.namespace)
                    }
                    .sheet(isPresented: $show, content: {
                        Details(setid: setid, data: recipes)
                    })
                     
                }
                .padding(.trailing)
                .background(Color.white)
                .cornerRadius(15)
            }
            
        }//End VStack
    }//End body
}
Details.swift
 
//
//  Details.swift
//  Test
//
//  Created by Cairocoders
//

import SwiftUI

struct Details: View {
    
    var setid: Int
    var data : Recipe
    var body: some View {
        //    Text("\(setid)")
        //    Text(data.name)
        VStack {
            Image(data.image)
                .resizable()
                .aspectRatio(contentMode: .fill)
            Text(data.name)
                .font(.title)
                .fontWeight(.medium)
            Form {
                Section {
                    HStack {
                        VStack {
                            Text("Detail")
                                .foregroundColor(.gray)
                                .font(.callout)
                                .frame(alignment: .leading)
                            Text(data.details)
                                .foregroundColor(.gray)
                                .font(.callout)
                                .frame(alignment: .leading)
                        }
                    }
                    HStack {
                        Text("Rating")
                        Spacer()
                        ForEach(1...5,id: \.self) {rating in
                            Image(systemName: "star.fill")
                                .foregroundColor(self.data.rating >= rating ? .yellow : .gray)
                        }
                    }
                    
                }

            }
        }
        .environment(\.colorScheme, .light)
    }
}

Related Post