URL Shortener ب Laravel 9 Darija & Vuejs 3 Darija الجزء الرابع

imadbelasri Laravel
LA

فهاد الجزء الرابع من URL Shortener ب Laravel 9 Darija & Vuejs 3 Darija غادي نزيدوا ل Home Component و store ب Pinia و منبعد نزيدو الملفات الأساسية لي فيهم styles css و js.


نظرة سريعة بالفيديو


1- إضافة store ب pinia

ف dossier js زيد dossier stores فيه زيد fichier سميه useLinkStore.js فيه غادي يكونوا les fonctions لي غادي نحتاجوا.

الكود ديال الملف هو :

                                                    
                                                        //
import { defineStore } from 'pinia';
import Swal from 'sweetalert2';

export const useLinkStore = defineStore('links', {
    state: () => ({ 
        links: [],
        errors: null,
        current_page: 1,
        link: {
            updating: false,
            data: {
                full_url: '',
                url_desc: ''
            }
        }
    }),
    getters: {
        getLinks: (state) => state.links.data,
        getValidationErrors: (state) => state.errors
    },
    actions: {
        async addLink(user_id){
            this.errors = null;
            try {
                await axios.post('/api/add/url', {
                    full_url: this.link.data.full_url,
                    url_desc: this.link.data.url_desc,
                    user_id
                });
                this.fetchLinks(user_id);
                this.link = {
                    updating: false,
                    data: {
                        full_url: '',
                        url_desc: '',
                    }
                };
                this.errors = null;
                Swal.fire({
                    position: 'top-end',
                    icon: 'success',
                    title: 'Your link has been saved',
                    showConfirmButton: false,
                    timer: 2500
                });
            } catch (error) {
                this.errors = error.response && error.response.data.errors;
                console.log(error);
            }
        },
        async fetchLinks(user_id) {
            try {
                const response = await axios.get(`/api/user/urls/${user_id}`);
                this.links = response.data;
            } catch (error) {
                console.log(error);
            }
        },
        deleteLink(shorten_url, user_id){
            try {
                Swal.fire({
                    title: 'Are you sure?',
                    text: "You won't be able to revert this!",
                    icon: 'warning',
                    showCancelButton: true,
                    confirmButtonColor: '#3085d6',
                    cancelButtonColor: '#d33',
                    confirmButtonText: 'Yes, delete it!'
                }).then(async (result) => {
                    if (result.isConfirmed) {
                        await axios.delete(`/api/url/delete/${shorten_url}`);
                        this.fetchLinks(user_id);
                        Swal.fire(
                            'Deleted!',
                            'Your link has been deleted.',
                            'success'
                        )
                    }
                });
            } catch (error) {
                console.log(error);
            }
        },
        async next(user_id) {
            try {
                const response = await axios.get(`/api/user/urls/${user_id}?page=${this.current_page += 1}`);
                this.links = response.data;
            } catch (error) {
                console.log(error);
            }
        },
        async previous(user_id) {
            try {
                const response = await axios.get(`/api/user/urls/${user_id}?page=${this.current_page -= 1}`);
                this.links = response.data;
            } catch (error) {
                console.log(error);
            }
        },
        editLink(url){
            this.errors = null;
            this.link = {
                updating: true,
                data: url
            };
        },
        async updateLink(user_id){
            this.errors = null;
            try {
                await axios.put(`/api/urls/${this.link.data.shorten_url}`, {
                    full_url: this.link.data.full_url,
                    url_desc: this.link.data.url_desc,
                    user_id
                });
                this.fetchLinks(user_id);
                this.link = {
                    updating: false,
                    data: {
                        full_url: '',
                        url_desc: '',
                    }
                };
                this.errors = null;
                Swal.fire({
                    position: 'top-end',
                    icon: 'success',
                    title: 'Your link has been updated',
                    showConfirmButton: false,
                    timer: 2500
                });
            } catch (error) {
                this.errors = error.response && error.response.data.errors;
                console.log(error);
            }
        },
        cancelEdit(){
            this.errors = null;
            this.link = {
                updating: false,
                data: {
                    full_url: '',
                    url_desc: ''
                }
            };
        }
    },
});
                                                    
                                                

2- إضافة ل Home Component

داخل dossier components زيد fichier Home.vue لي غادي نعرضوا فيه الروابط ديالنا مع فورم الإضافة.

الكود ديال الملف هو :

                                                        
                                                            //
<template>
    <div class="row">
        <CreateLink />
        <LinksList />
    </div>
</template>

<script setup>
    import CreateLink from '@/components/CreateLink.vue';
    import LinksList from '@/components/LinksList.vue';
    import { provide } from 'vue';

    provide('user_id', props.user_id);

    const props = defineProps({
        user_id: {
            type: Number,
            required: true
        }
    });
</script>

<style>

</style>
                                                        
                                                    

3- إضافة الملف app.blade.php

داخل dossier views  زيد dossier layouts فيه زيد fichier app.blade.php لي غادي يكونوا فيه روابط css و js.

الكود ديال الملف هو :

                                                        
                                                            //
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <title>Laravel Url Shortener</title>
</head>
<body class="bg-light">
    <div class="container" id="app">
        @include('layouts.navbar')
        @yield('content')
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
    @vite('resources/js/app.js')
</body>
</html>
                                                        
                                                    

4- إضافة الملف navbar.blade.php

دائما داخل dossier layouts زيد fichier navbar.blade.php لي غادي تكون فيه ل Menu ديالنا.

الكود ديال الملف هو :

                                                        
                                                            //
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm rounded">
    <div class="container-fluid">
      <a class="navbar-brand" href="{{url('/')}}">Url Shortener</a>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav me-auto mb-2 mb-lg-0">
          <li class="nav-item">
            <a class="nav-link active" aria-current="page" href="{{url('/')}}">Home</a>
          </li>
          <li class="nav-item dropdown">
            <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
              Account
            </a>
            <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
              @guest
                <li><a class="dropdown-item" href="{{route('register')}}">Register</a></li>
                <li><a class="dropdown-item" href="{{route('login')}}">Login</a></li>
              @endguest
              @auth
                <li><a class="dropdown-item" href="#">{{auth()->user()->name}}</a></li>
                <li><a 
                      onclick="document.getElementById('logoutForm').submit();"
                      class="dropdown-item" href="#">Logout</a></li>
                <form id="logoutForm" action="{{route('logout')}}" method="post">@csrf</form>
              @endauth
            </ul>
          </li>
        </ul>       
      </div>
    </div>
</nav>