InfyOm Blog

latest-post

Last week, we run into a problem for one of the large Gatsby + ReactJS + Laravel projects in hosting which is hosted with Apache Webserver on Amazon AWS EC2. The problem we were facing was, for some reason, when we reload the Gatsby website, it was giving a 404 error page.

If you open a home page and then a normal visit then the website will fully function, but if you reload the page then it gives an error. And we found it happens when we are using Dynamic routing of React Route in Gatsby as per show in Gatsby documentation here.

Also, what we found, if we test the website build with gatsby serve then it works fine. But while using Apache, it behaves differently and we found that this problem has been faced by lots of people over the internet.

So what we came up with is, we used gatsby serve with an apache proxy. Here is how we did it,

Step 1 - Setup Project

As a first step, clone the project on the server and run a command, gatsby build to create a gatsby build.

Step 2 - Setup PM2 for Gatsby Serve

The next step that we need to do is run gatsby serve. But as you know, we can not run this command directly via console, because as you exit from the console, the command will be terminated.

So we will be using pm2 package, a NodeJS utility that is used to run nodejs apps.

For that, we will need to install pm2 globally. Run the following command to install it,

npm install pm2 -g

You can find other installation ways here if you need.

Once the installation has been done, let's run the gatsby serve command via pm2. For that run the following command from the gatsby project folder,

pm2 start gatsby --name my-web-app -- serve

where my-web-app you can replace with the name of your app.

Once, it's running, try to test it, if it's working correctly by opening the URL http://your-ip-address:9000/. Make sure, port 9000 is opened on your server for traffic.

Step 3 - Configure Apache

Once, gatsby serve is working and tested. The next step is to configure apache to proxy all port 80 traffic to port 9000.

For that, edit your apache conf file (or virtual host conf file), and add the following lines (or configure it to something like the following),

<VirtualHost *:80>
        ServerName my-web-app.infyom.com

        ServerAdmin webmaster@infyom.com

        ProxyRequests On
        ProxyPass / http://localhost:9000/
        ProxyPassReverse / http://localhost:9000/

        ErrorLog ${APACHE_LOG_DIR}/my-web-app.infyom.com.error.log
        CustomLog ${APACHE_LOG_DIR}/my-web-app.log combined

        ......
        # any other options below as per your need
        ......
</VirtualHost>

The next step you need to do is restart your apache server by,

sudo service apache2 restart

And then you can just open the URL https://my-web-app.infyom.com and it should work fine.

Bonus

New Deployment

Whenever you deploy a new code, you again need to run gatsby build and then pm2 restart my-web-app. Then only it will take new changes.

Troubleshooting

Sometimes, we found that we need to restart apache as well after the new deployment. so if you run into any trouble, then make sure to restart apache as well and it should solve the problem.

I hope it may help you to resolve your 404 problem.

July 16, 20213 minutesuserMitul Golakiya

Posts

post

We have recently developed a site into the gatsby.

We have a blog site and hosted it on a different domain but now we want to move to one place at our main site. now, we have challenges for displaying dynamic blogs on the gatsby site.

Finally, I found that gatsby provides support to render dynamic blogs as a static page. when build created that time fetch the blogs from the server and create a static page for all the blogs.

Gatsby is a very good platform and manages such a kind of thing easily.

So, I will show you how to create static pages from the API response into the Gatsby site.

Here are the steps you need to follow correctly.

Steps 1

Create a one blog file where you want to load a blog in your design.

For an ex. I created a file `blog/index.js` inside the component directory and the code looks like this,


Steps 2

Open a file `gatsby-node.js`

Declare the const for the API URL at the beginning of the file.

const blogURL = 'http://blog-api.com/api/posts';

We need to create an instance of the  `node-fetch` for fetching a data from API server.

const fetch = require(`node-fetch`);
Import the path for a resolve the page while creating a static page.
const path = require('path');
See the example how to create a static page from APIs. code look's like,
exports.createPages = (async ({graphql, actions}) => {
    const blogs = await fetch(blogURL);
    blogs.data.forEach((blog) => {
        createPage({
            path: 'blog/' + blog.slug,
            component: path.resolve(`./src/components/blog/index.js`),
            context: {
                // Data passed to context is available
                // in page queries as GraphQL variables.
                slug: blog.slug,
                blog: blog,
            },
        })
    })
Now we are done, and you can access blogpage via slug.


November 12, 20201 minuteauthorShailesh Ladumor
post
Zoom Marketplace is providing APIs to create zoom meeting direct using the web interface and calling its API. So first of you need to create your zoom ap into zoom marketplace and need to generate the API Keys and credentials.

Create a Zoom Application
  1. Go to Zoom marketplace and do sign in
  2. Click Develop button on header and select Build App menu.
  3. Choose the JWT and create an application with the app name that you want.
  4. Input required information and click Continue until your app will be activated. 
I hope you already have installed fresh laravel. now you have to add the following packages to your composer.json  to integrate the zoom API.

composer require firebase/php-jwt
composer require guzzlehttp/guzzle
And Now run composer update

And don't forget that we also need to modify .env files to set the zoom API credentials.

ZOOM_API_URL="https://api.zoom.us/v2/"
ZOOM_API_KEY="INPUT_YOUR_ZOOM_API_KEY"
ZOOM_API_SECRET="INPUT_YOUR_ZOOM_API_SECRET"

You can find the zoom credentials from your zoom app.

Now just copy given ZoomMeetingTrait to your controller and call-related methods.

<?php

namespace
App\Traits;

use GuzzleHttp\Client;
use Log;

/**
 * trait ZoomMeetingTrait
 */
trait
ZoomMeetingTrait
{
    public $client;
    public $jwt;
    public $headers;

    public function __construct()
    {
        $this->client = new Client();
        $this->jwt = $this->generateZoomToken();
        $this->headers = [
            'Authorization' => 'Bearer '.$this->jwt,
            'Content-Type'  => 'application/json',
            'Accept'        => 'application/json',
        ];
    }
    public function generateZoomToken()
    {
        $key = env('ZOOM_API_KEY', '');
        $secret = env('ZOOM_API_SECRET', '');
        $payload = [
            'iss' => $key,
            'exp' => strtotime('+1 minute'),
        ];

        return \Firebase\JWT\JWT::encode($payload, $secret, 'HS256');
    }

    private function retrieveZoomUrl()
    {
        return env('ZOOM_API_URL', '');
    }

    public function toZoomTimeFormat(string $dateTime)
    {
        try {
            $date = new \DateTime($dateTime);

            return $date->format('Y-m-d\TH:i:s');
        } catch (\Exception $e) {
            Log::error('ZoomJWT->toZoomTimeFormat : '.$e->getMessage());

            return '';
        }
    }

    public function create($data)
    {
        $path = 'users/me/meetings';
        $url = $this->retrieveZoomUrl();

        $body = [
            'headers' => $this->headers,
            'body'    => json_encode([
                'topic'      => $data['topic'],
                'type'       => self::MEETING_TYPE_SCHEDULE,
                'start_time' => $this->toZoomTimeFormat($data['start_time']),
                'duration'   => $data['duration'],
                'agenda'     => (! empty($data['agenda'])) ? $data['agenda'] : null,
                'timezone'     => 'Asia/Kolkata',
                'settings'   => [
                    'host_video'        => ($data['host_video'] == "1") ? true : false,
                    'participant_video' => ($data['participant_video'] == "1") ? true : false,
                    'waiting_room'      => true,
                ],
            ]),
        ];

        $response =  $this->client->post($url.$path, $body);

        return [
            'success' => $response->getStatusCode() === 201,
            'data'    => json_decode($response->getBody(), true),
        ];
    }
   
    public function update($id, $data)
    {
        $path = 'meetings/'.$id;
        $url = $this->retrieveZoomUrl();

        $body = [
            'headers' => $this->headers,
            'body'    => json_encode([
                'topic'      => $data['topic'],
                'type'       => self::MEETING_TYPE_SCHEDULE,
                'start_time' => $this->toZoomTimeFormat($data['start_time']),
                'duration'   => $data['duration'],
                'agenda'     => (! empty($data['agenda'])) ? $data['agenda'] : null,
                'timezone'     => 'Asia/Kolkata',
                'settings'   => [
                    'host_video'        => ($data['host_video'] == "1") ? true : false,
                    'participant_video' => ($data['participant_video'] == "1") ? true : false,
                    'waiting_room'      => true,
                ],
            ]),
        ];
        $response =  $this->client->patch($url.$path, $body);

        return [
            'success' => $response->getStatusCode() === 204,
            'data'    => json_decode($response->getBody(), true),
        ];
    }
   
    public function get($id)
    {
        $path = 'meetings/'.$id;
        $url = $this->retrieveZoomUrl();
        $this->jwt = $this->generateZoomToken();
        $body = [
            'headers' => $this->headers,
            'body'    => json_encode([]),
        ];

        $response =  $this->client->get($url.$path, $body);

        return [
            'success' => $response->getStatusCode() === 204,
            'data'    => json_decode($response->getBody(), true),
        ];
    }

    /**
     *
@param string $id
     *
     *
@return bool[]
     */
    public function
delete($id)
    {
        $path = 'meetings/'.$id;
        $url = $this->retrieveZoomUrl();
        $body = [
            'headers' => $this->headers,
            'body'    => json_encode([]),
        ];

        $response =  $this->client->delete($url.$path, $body);
       
        return [
            'success' => $response->getStatusCode() === 204,
        ];
    }
}
And add the following constants to your controller.

const MEETING_TYPE_INSTANT = 1;
const MEETING_TYPE_SCHEDULE = 2;
const MEETING_TYPE_RECURRING = 3;
const MEETING_TYPE_FIXED_RECURRING_FIXED = 8;
So the final controller will look like, 


<?php

namespace
App\Http\Controllers;

use App\Models\ZoomMeeting;
use App\Traits\ZoomMeetingTrait;
use Illuminate\Http\Request;

class MeetingController extends AppBaseController
{
    use ZoomMeetingTrait;

    const MEETING_TYPE_INSTANT = 1;
    const MEETING_TYPE_SCHEDULE = 2;
    const MEETING_TYPE_RECURRING = 3;
    const MEETING_TYPE_FIXED_RECURRING_FIXED = 8;

    public function show($id)
    {
        $meeting = $this->get($id);

        return view('meetings.index', compact('meeting'));
    }

    public function store(Request $request)
    {
        $this->create($request->all());

        return redirect()->route('meetings.index');
    }

    public function update($meeting, Request $request)
    {
        $this->update($meeting->zoom_meeting_id, $request->all());

        return redirect()->route('meetings.index');
    }

    public function destroy(ZoomMeeting $meeting)
    {
        $this->delete($meeting->id);

        return $this->sendSuccess('Meeting deleted successfully.');
    }
}

So this is all you need to integrate zoom API, so easy 😊  Right. Enjoy the code. 
November 11, 20201 minuteauthorVishal Ribdiya
post

Introduction

How to maximize profits is on the minds of most business owners. There are only two ways to do this: increase prices or reduce costs. You cannot simply say that you are going to increase the profit of your business without a specific strategy. All you can do to increase profits is to improve the variables that ultimately determine your profitability. Consider the following strategies to make more money for you and your business in 2021.

1. Improve your website

People are using your website to research your company before doing business with you. Can you improve their experience and build their trust so they can use your product or service? There are four things you should clearly do on your website:
  • Explain who you are and what you sell
  • Entice a potential customer to buy
  • Make it easy to buy a product or service
  • There is a way to easily contact sales or customer support with questions

2. Invest in your business

At first glance, you would hesitate to put more money into your business. Especially when you’re trying to figure out how to make more money, not less. Often, especially in times of turmoil where new opportunities arise, the best decision is a short-term price for long-term payments.

3. Increase your advertising

You will not hesitate to spend money on advertising. Maybe you’ve been burned by a marketer in the past who promised results and didn’t get results. Or you tried advertising yourself, such as Facebook ads, and you don't think it works.

4. Raising prices

Both of these strategies are a thoughtful and unpleasant option in today’s economic environment. Still, sometimes, to stay in business, you need to raise prices. To determine the price, consider:
  • How much does it cost you to make a product
  • How much does it cost to deliver
  • Costs for running a business - including administration and employee salaries
  • Competitive price
  • The last time you raised a price
After reviewing this data, determine a possible reasonable price increase. Include any pricing data in your business plan so that if you choose to review it later, you can.
Next, deliver this increase to customers. Explain why you came to this decision. If there’s any way to add value to a product without cutting a profit, do it and let customers know they’re getting more.

5. Follow the 80/20 rule

The 80/20 rule is to focus your most important efforts on your most valued customers. The idea is that 20% of your customers usually bring in 80% of your revenue; These are the people you want to focus on.
On the flip side, 20% of your customers frequently present 80% of your problems. Identify those problem-customers and fire them to free up your time on more positive business activities.

6. Cut costs

One way to think about reducing costs is to consider the profit leverage effect (PLE). P.L.E. The idea is that every dollar saved in the production of goods or delivery of services adds a dollar profit to your bottom line without selling too much.
Check your current processes to reduce costs:
  • Are there areas where you can improve efficiency?
  • Negotiate cheap products or services?
  • Will adopting new software or renting a service save you money in the long run?
We will see more points in our next tutorial.
November 08, 20203 minutesauthorAnkit Kalathiya
post
Hello, friend short cut way all people like. but remember a short cut is improved your self and save time it's a very good way. so in this blog learning the android studio shortcut key.use all short cut key and save time and performance improve 

image1.png 70.61 KB
Search Keys :


  • Shift+Shift — Search Every Where
  • Ctrl+F — Find Text within a Single File
  • Ctrl+Shift+F-Find Text in All Files
  • Ctrl+R — Replace Selected Text in a Single File
  • Ctrl+Shift+R — Replace Selected Text in all Files (Be Careful while Using This)
  • Ctrl+Shift+A —Search for IDE Commands
Navigation Keys  :

  • Ctrl+N — Navigate to Class
  • Ctrl+Shift+N — Navigate to a File
  • Ctrl+B — Jump to Declarations
  • Alt+ ↑ — Jump to the Previous Method
  • Alt+↓ — Jump to Next Method
  • Ctrl+G — Jump to Line
  • Ctrl+E — Recent Files
  • Ctrl+Shift+Back Space — Jump to Last Edited Location
  • Ctrl+B — Find Declarations
  • Ctrl+Left Mouse(or)Ctrl+Alt+F7— Show Usage
  • Alt + F7 / Ctrl + F7 — Find usages /Find usages in file
  • Ctrl+Shift+B — Find Implementations
  • F3 — Find Next
  • Shift+F3 — Find Previous
BookMark Keys :

  • F11 — Toggle bookmark
  • Ctrl+F11 — Toggle bookmark with the mnemonic(0–9 or A-Z)
  • Ctrl +(0–9) — Go to numbered bookmark
  • Shift+F11 — Show all Bookmarks
  • Ctrl + Shift + F7 — Highlight usages in file
Selection Keys :

  • Ctrl + W — Extend selection (selects a word->line->method->Class )
  • Ctrl +Shift+ W — Decrease Selection
  • Alt + J — Select next occurrence
  • Ctrl + Alt + Shift + J — Select all occurrences
  • Alt + Shift + J — Unselect occurrence
  • Ctrl+Shift+V — Paste from recent buffers (from a History of Copied Contents)
Editing Keys :

  • Ctrl+F6  — Refractor Code
  • Ctrl+D — Duplicate a Line/Selected part
  • Ctrl+Y — Delete a Line/Selected part
  • Ctrl+Q — Quick Documentation
  • Ctrl + Space — Code completion
  • Ctrl+Shift+Space — Smart code completion (by expected type removes unrelated suggestions)
  • Alt+Insert — Generate Code
  • Ctrl+J — Insert Live template
  • Ctrl + O — Override methods
  • Ctrl + I — Implement methods
  • Ctrl + Alt + T — Surround with…
  • Ctrl + / — Comment / uncomment with line comment
  • Ctrl + Shift + / — Comment / uncomment with block comment
  • Ctrl+Alt+L — Reformat code
Run  :

  • Ctrl + F9 — Compile and Run Make a project
  • Ctrl + Shift + F9 — Compile selected file, package or module
  • Shift + F10 — Run
  • Shift + F9 — Debug
  • Ctrl + Shift + F10 — Run context configuration from editor
Debugging  :

  • F8 / F7 — Step over / into
  • Shift + F7 / Shift + F8 — Smart step into/Step out
  • Alt + F9 — Run to cursor
  • Alt + F8 — Evaluate expression
  • F9 — Resume program
  • Ctrl + F8 — Toggle break point
  • Ctrl + Shift + F8 — View breakpoints

November 05, 20202 minutesauthorPankaj Valani
post
what is a SplashScreen?

A splash screen is a screen that appears when you open an app on your mobile device. So, we can say that it is the first impression for the user. It is commonly used to show an application logo or an image associated with an application.



















Implementation

So instead of using a layout file, we'll refer to the splash screen as the background of the activity theme. first, create an XML drawable splash_background.xml inside res/drawable folder in

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@color/white" />
    
    <item
        android:drawable="@drawable/ic_icon_vector"
        android:gravity="center" />

</layer-list>
 next step, set splash_groundground.xml as the background for your splash activity in the theme. Add a new splash to your splash activity.


<!-- Splash Screen theme. -->
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="android:windowBackground">@drawable/splash_background</item>
</style>
Add your theme to AndroidManifest.xml as your splash activity theme.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.exmple.splash">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme">
        
        <activity
            android:name=".SplashActivity"
            android:theme="@style/SplashTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
Create a blank activity for SplashActivity.java without XML. This class will only redirect to MainActivity.java.

public class SplashActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startActivity(new Intent(SplashActivity.this, MainActivity.class));
        finish();
    }
}



November 02, 20201 minuteauthorVivek Beladiya
post
We are recently developed a site into the gatsby. basically contact us feature is common in all website.
and we are implementing Mailchimp because it's a very popular platform in email market.

So, I will show you how to setup a Mailchimp in the Gatsby site.

## Using gatsby-source-mailchimp

Use your Mailchimp API key to download your campaigns into Gatsby’s GraphQL data layer!

Install the package by running the following command: `npm i gatsby-source-mailchimp --save`

### How to configure
Once the installation is complete, you can now add this plugin to your gatsby-config.js, like so:

Configure mailchimp Key and add this {resolve: `gatsby-source-mailchimp`} into the plugins array. code looks like

```
module.exports = {
  // ...
  plugins: [
    {
      resolve: 'gatsby-source-mailchimp',
      options: {
        // Avoid including your key directly in your file.
        // Instead, opt for adding them to .env files for extra
        // security ;)
        key: 'asd712jdas90122jdas90122jkadsd1-usXX',
        rootURL: 'https://usXX.api.mailchimp.com/3.0',
      },
    },
  ],
  // ...
}
```

Above is the minimal configuration required to have it work. By default,
This plugin was made out of a specific necessity, so it doesn't cover all of Mailchimp’s data sources, focusing only on campaigns.

this plugin are provide few options. you can refer here.

## Using `.env` variables to hide your key
If you don’t want to attach your API key to the repo, you can easily store it in .env files by doing the following:

```
// In your .env file
MAILCHIMP_KEY = 'asd712jdas90122jdas90122jkadsd1-usXX';
```

```
// In your gatsby-config.js file
require('dotenv').config({
  path: `.env.${process.env.NODE_ENV}`,
});

module.exports = {
  // ...
  plugins: [
    {
      resolve: 'gatsby-source-mailchimp',
      options: {
        key: process.env.MAILCHIMP_KEY,
        rootURL: 'https://usXX.api.mailchimp.com/3.0',
        // ...
      },
    },
  ],
  // ...
};
```


October 31, 20201 minuteauthorShailesh Ladumor
post
We all know that recruitment becomes tough day by day as the competition is growing in the market. If I talk about the IT industry each Organisation is fighting hard to find candidates for various IT profiles. Now all IT HRs are in trouble with lots of targets of hiring and it’s not as easy as ABC in practical. Sometimes it takes a very long time to get a response from the market for a particular profile. Still, we need to pay attention to many things to make a smooth & effective recruitment process.

1.Build your network
2.Attractive & Innovative Job Posting
3. Choose Right Person & Be polite to others
4.Communication: Be good listener 
5. Affordability





6. Talent v/s Experience


1.Build your network :
“Network is net-worth”. Without a network, it is too difficult to reach the right one. Every HR needs to develop a professional network. If I talk about the IT field we need to develop a network on LinkedIn to reach maximum people. Send connection requests to them Talk with them and scan candidates over there. Not only this we can use Facebook as well as the young generation addicted to it and target the suitable person over there.

2. Attractive & Innovative Job posting:
We are living in a competitive era, where we are fighting hard to even get responses from the market side and that’s why we need to be creative & innovative while preparing Job descriptions. prepare star lines to attract people, use different ways to post the job, give information regarding facilities the company is providing, any other attraction if the company has. 

3. Choose Right Person & Be polite to others :
After receiving lots of CVs for a particular role, it’s too critical to scan all and invite a few for Interviews. After interviewing all people we need to think about the best suitable person for the job.
HR needs to develop a habit to wish all the best to the not selected candidate. It creates a positive image of the company in that person's mind. And yes the second thing is, never use the “REJECTED” word for any candidate just say ‘unfortunately you are not selected’, even you can say ‘sorry to say that you are not best fit for the job’. I am saying this because there is no rejection, only the thing is our requirement and the capabilities of the applicant are quite different. 

4. Communication: Be good listener :
Communication skill is essential for all HR Professionals. While interacting with candidates, be open, communicate each and everything. HR needs to communicate all the rules, regulations, policies, agreement terms & conditions (If you have), Training period, and the pay scale during training ( If you are hiring fresher), etc. After discussing all the required things with the candidate, if the candidate found comfortable then only arrange his/her interview otherwise it will be a waste of time for both Employers as well as Employees.

While taking interviews not only ask questions and get answers, be a good listener. Listening to the candidate with patience may be the way of presenting is different but one has really deep knowledge about the same and at least gives the chance to present.

5. Affordability-
Always keep in mind the budget of the company for a particular position and don’t waste your valuable time with overqualified people. Say NO to them with respect, you can say ‘we don't have any requirement regarding your profile’.

6. Talent v/s Experience:
While recruiting people  never fixed the experience parameter as it may be possible that the less experienced person has more talent. Carefully analyse the person and then only select the best out of them. 

I will discuss more tips on recruitment in my next blog….



October 28, 20203 minutesauthorMariyam Bemat
post
Cardview is a widget provided by Android to create a new look and functional UI. You can build your app with the following examples to make it look more professional. Cardview is a wonderful concept that makes your user experience better than the Android UI. Cardview is an Android Lollipop released with Android 5.0.















Customized CardView


First, add a CardView dependency to the application-level build.gradle file.

dependencies {
    implementation ‘androidx.cardview:cardview:1.0.0’
}
Then create a drawable background for the cards. For that, create a new drawable resource file inside the drawable folder.
res > drawable > New > Drawable Resource File.





background1.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient android:startColor="#FFAB00"
        android:endColor="#FFAB00">
    </gradient>
</shape>

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient android:startColor="#0091EA"
        android:endColor="#00BFA5">
    </gradient>
</shape>

Screenshot 2020-12-19 at 10.52.33 PM.png 4.64 KB
background3.xml








<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient android:startColor="#AEEA00"
        android:endColor="#FFD600">
    </gradient>
</shape>
Screenshot 2020-12-19 at 10.52.25 PM.png 4.75 KB
Now create a card view in the main XML file. Here I used  LinearLayout as the root widget, after using the card view. Below the codes that give you an idea of how to customize the card.
You can change it according to your needs.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="173dp"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="20dp"
        app:cardCornerRadius="8dp">

        <LinearLayout
            android:id="@+id/linearLayout1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/bg1"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="30dp"
                android:layout_marginTop="20dp"
                android:layout_marginEnd="30dp"
                android:orientation="horizontal">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Assam"
                        android:textColor="#000000"
                        android:textSize="22sp" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Current Location"
                        android:textColor="#000000"
                        android:textSize="14sp" />
                </LinearLayout>

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginStart="30dp"
                android:layout_marginTop="20dp"
                android:layout_marginEnd="30dp"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="25"
                    android:textColor="#000000"
                    android:textSize="28sp" />

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="6dp"
                        android:text="o"
                        android:textColor="#000000"
                        android:textSize="13sp" />

                </LinearLayout>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="18 %"
                    android:textColor="#000000"
                    android:textSize="14sp" />

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentEnd="true"
                        android:layout_marginStart="6dp"
                        android:text="11.25 AM"
                        android:textColor="#000000"
                        android:textSize="14sp" />
                </RelativeLayout>
            </LinearLayout>
        </LinearLayout>
    </androidx.cardview.widget.CardView>

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="173dp"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="20dp"
        app:cardCornerRadius="8dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/bg2"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="30dp"
                android:layout_marginTop="20dp"
                android:layout_marginEnd="30dp"
                android:orientation="horizontal">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Delhi"
                        android:textColor="@color/white"
                        android:textSize="22sp" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="2 days ago"
                        android:textColor="@color/white"
                        android:textSize="14sp" />
                </LinearLayout>

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginStart="30dp"
                android:layout_marginTop="20dp"
                android:layout_marginEnd="30dp"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="39"
                    android:textColor="@color/white"
                    android:textSize="28sp" />

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="6dp"
                        android:text="o"
                        android:textColor="@color/white"
                        android:textSize="13sp" />

                </LinearLayout>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="35 %"
                    android:textColor="@color/white"
                    android:textSize="14sp" />

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentEnd="true"
                        android:layout_marginStart="6dp"
                        android:text="01.05 PM"
                        android:textColor="#D6D6D6"
                        android:textSize="14sp" />
                </RelativeLayout>
            </LinearLayout>
        </LinearLayout>
    </androidx.cardview.widget.CardView>

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="173dp"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="20dp"
        app:cardCornerRadius="8dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/bg3"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="30dp"
                android:layout_marginTop="20dp"
                android:layout_marginEnd="30dp"
                android:orientation="horizontal">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Darjeeling"
                        android:textColor="#000000"
                        android:textSize="22sp" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="2 weeks ago"
                        android:textColor="#000000"
                        android:textSize="14sp" />
                </LinearLayout>

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginStart="30dp"
                android:layout_marginTop="20dp"
                android:layout_marginEnd="30dp"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="12"
                    android:textColor="#000000"
                    android:textSize="28sp" />

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="6dp"
                        android:text="o"
                        android:textColor="#000000"
                        android:textSize="13sp" />

                </LinearLayout>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="9 %"
                    android:textColor="#000000"
                    android:textSize="14sp" />

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentEnd="true"
                        android:layout_marginStart="6dp"
                        android:text="05.00 AM"
                        android:textColor="#000000"
                        android:textSize="14sp" />
                </RelativeLayout>
            </LinearLayout>
        </LinearLayout>
    </androidx.cardview.widget.CardView>
</LinearLayout>
Output :-

October 25, 20201 minuteauthorVivek Beladiya