Nextjs — я слышал об этой платформе React для масштабируемых производственных приложений, и мне захотелось ее проверить! Я решил использовать контактное приложение, и, поскольку я узнаю что-то новое, почему бы не изучить и Tailwind. Так что вместо того, чтобы покупать один, почему бы не купить два по цене одного.

Немного не по теме, но One Piece — величайшее аниме всех времен!!!

Возвращаясь к тому, о чем я говорил, я здесь не для того, чтобы учить вас Nextjs, Tailwind или Flutter, я просто показываю вам, что я сделал, и надеюсь, вам это понравится. Давайте поймем несколько вещей:

Nextjs. Next.js — это гибкая инфраструктура React, которая дает вам строительные блоки для создания быстрых веб-приложений.

Prisma: Prisma помогает разработчикам приложений создавать быстрее и делать меньше ошибок с помощью набора инструментов баз данных с открытым исходным кодом для PostgreSQL, MySQL, SQL Server, SQLite. , MongoDB и CockroachDB.

SQLite: SQLite — это библиотека на языке C, которая реализует небольшой, быстрый, автономный, высоконадежный, полнофункциональный механизм базы данных SQL. . SQLite — самая используемая СУБД в мире. SQLite встроен во все мобильные телефоны и большинство компьютеров и входит в состав бесчисленного множества других приложений, которые люди используют каждый день.

Flutter: Flutter преобразует процесс разработки приложений. Создавайте, тестируйте и развертывайте красивые мобильные, веб-приложения, десктопные и встроенные приложения из единой кодовой базы.

Tailwind: Tailwind — быстро создавайте современные веб-сайты, не выходя из HTML-кода.

Теперь давайте погрузимся прямо в:

Это то, что мы будем строить; простое приложение для контактов, которое поможет вам: создать контакт, просмотреть его, обновить и удалить. Давайте создадим наши приложения:

Prisma хорошо интегрируется с Next.js. Next.js сочетает в себе внешний и внутренний код. Это означает, что мы можем создавать компоненты пользовательского интерфейса в Next.js, а также создавать маршруты API в том же приложении Next.js, поэтому Next.js содержит клиент и сервер. Prisma является соединением с базой данных, что делает его идеальным для вызова в нашем приложении Next.js для извлечения данных из серверной части для нас. В Next.js есть много способов получить данные. В Next.js есть три уникальные функции, которые мы можем использовать для получения данных для предварительного рендеринга, но я буду использовать только одну.

getServerSideProps (рендеринг на стороне сервера): запускается, когда страница предварительно обрабатывается при каждом запросе. Здесь мы также можем вызвать клиентские методы Prisma для получения данных, которые мы хотим передать компонентам Next.js.

npx create-next-app contactsapp //(creates the Nextjs App)

Переместитесь в папку: cd contactapp. Мы установим следующие зависимости:

npm install -D prisma //(add prisma)
npm install @prisma/client //(Prisma client for JavaScript. It only runs on Node.js.)

Затем запустите:

npx prisma init 

для инициализации Prisma и создания папки prisma внутри проекта contactapp и файла .env. Папка prisma будет содержать файл schema.prisma, здесь мы объявляем наши модели базы данных Prisma. Затем мы настраиваем соединения Prisma с нашей базой данных SQLite.

generator client {
  provider = "prisma-client-js"
}
 
datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

model Contact {
  id String @id @default(cuid())
  firstname String
  lastname String
  email String
}

Это то, что у меня есть. Контакт — это модель, с которой мы работаем, вы можете добавить больше полей, если хотите. Затем вы запускаете миграции для создания таблицы:

npx prisma migrate dev

Теперь мы создадим наши компоненты -
components/AddScreen.js:

import { useForm } from 'react-hook-form';
 
const FormError = ({ errorMessage }) => {
    return <p className="text-red-300 mt-1">{errorMessage}</p>;
  };
 
 
const AddScreen = ({ contacts, AddContactFormProps }) => {
    const { register, handleSubmit, errors } = useForm();
    console.log("The addCContact", AddContactFormProps);
    return (
        <form className="flex flex-col" onSubmit={handleSubmit(AddContactFormProps)}>
            <div className="md:col-span-1 md:flex md:justify-start flex-col bg-slate-900 h-screen text-white px-3">
                <h1 className="font-bold">Add a Contact</h1>
                <div>
                    <div className="mb-4">
                        {/ <InputSpacer> /}
                            <input className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="firstname" type="text" placeholder="firstname" name='firstname'
                            {...register('firstname', { required: true })} />
                            {/* {errors.firstName && (
                                <FormError errorMessage="First Name is required" />
                            )} */}
                        {/ </InputSpacer> /}
                       
                    </div>
                    <div className="mb-4">
                        {/ <InputSpacer> /}
                            <input className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="lastname" type="text" placeholder="lastname" name='lastname'
                            {...register('lastname', { required: true })} />
                            {/* {errors.lastName && (
                                <FormError errorMessage="First Name is required" />
                            )} */}
                        {/ </InputSpacer> /}
                    </div>
                    <div className="mb-4">
                        {/ <InputSpacer> /}
                            <input className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="lastname" type="email" placeholder="email" name='email'
                            {...register('email', { required: true })} />
                            {/* {errors.email && (
                                <FormError errorMessage="First Name is required" />
                            )} */}
                        {/ </InputSpacer> /}
                    </div>
                    <div className="">
                        <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full" id="btnAdd"
                        type="submit">
                            Add
                        </button>
                    </div>
                </div>
                {/ <Script src="/main.js" strategy='lazyOnload' /> /}
            </div>
        </form>
     );
}
export default AddScreen;

components/DisplayScreen.js:

const DisplayScreen = ({ contacts, delContact }) => {
    console.log(contacts)
    return (
        <div className="px-16 bg-gray-100 md:col-span-2 h-screen">
            <h1 className="font-bold text-slate-800">All Contacts</h1>
            {
                contacts.map(contact => (
                    <div key={contact.id} className="bg-white rounded-md overflow-hidden shadow p-3 my-3 grid grid-cols-3 gap-3">
                        <div className="md:col-span-2">
                            <h1>{ contact.firstname } { contact.lastname }</h1>
                            <span className="text-sm font-bold">{ contact.email }</span>
                        </div>
                        <div className="md:col-span-1">
                            <button className="bg-red-500 text-white p-2 rounded-md hover:scale-125 hover:opacity-80" onClick={
                                () => delContact(contact)
                            }>Del</button>
                        </div>
                    </div>
                ))
            }
        </div>
     );
}
 
export default DisplayScreen;

страницы/index.js:

import { PrismaClient } from '@prisma/client'
import Head from 'next/head'
import { useState } from 'react'
import AddScreen from '../components/AddScreen'
import DisplayScreen from '../components/DisplayScreen'
 
const prisma = new PrismaClient()
 
export const getServerSideProps = async () => {
  const contacts = await prisma.contact.findMany()
  return {
    props: {
      initialContacts: contacts
    }
  }
}
 
const saveContact = async (contact) => {
  const response = await fetch('/api/contacts', {
    method: 'POST',
    body: JSON.stringify(contact),
    headers: {
      'Content-Type': 'application/json; charset=utf8'
    }
  })
 
  console.log("response", contact)
 
  if (!response.ok) {
    throw new Error(response.statusText)
  }
 
  return await response.json()
}
 
const delContact = async (contact) => {
  if (window.confirm("Do you want to delete this food?")) {
    await fetch('/api/deleteContact', {
      method: 'POST',
      body: JSON.stringify({
        id: contact.id
      }),
      headers: {
        'Content-Type': 'application/json; charset=utf8'
      }
    })
    // console.log("response", contact)
  }
}
 
export default function Home({ initialContacts }) {
  const [contacts, setContacts] = useState(initialContacts)
 
  return (
    <div className="">
      <Head>
        <title>Contact App</title>
        <meta name="description" content="Created by Connelblaze" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
 
      <div className="grid md:grid-cols-3">
     
        <AddScreen contacts = { initialContacts } AddContactFormProps = {async (data, e) => {
          try {
            await saveContact(data)
            setContacts([...contacts, data])
            e.target.reset()
          } catch (error) {
            console.log(error);
          }
        }} />
 
        <DisplayScreen contacts = { initialContacts } delContact = { delContact } />
      </div>
    </div>
  )
}

Как видите, мы использовали Fetch для связи с API.

Маршруты API. Маршруты API в Next.js хранятся в папке pages/api. Каждый файл и папка сопоставляются с конечной точкой API. Они обслуживаются по тому же URL-адресу, что и внешний код, localhost:3000. Так как localhost:3000/getAllContacts возвращает страницу всех контактов из приложения Next.js.
Теперь вам нужно создать маршруты API.

страницы/api/getAllcontacts.js:

import { PrismaClient } from "@prisma/client";
 
const prisma = new PrismaClient();
 
export default async (req, res) => {
  const data = req.body;
  try {
    const result = await prisma.contact.findMany();
    res.status(200).json(result);
  } catch (err) {
    console.log(err);
    res.status(403).json({ err: "Error occured." });
  }
};
This returns all contacts.
pages/api/contacts.js:
import { PrismaClient } from "@prisma/client"
 
const prisma = new PrismaClient();
 
export default async function handler(req, res) {
   
    if (req.method !== 'POST') {
        return res.status(405).json({ message: 'Method not allowed' });
      }
   
      try {
 
        const conatactData = req.body //JSON.parse(req.body);
       
        const saveContact = "Contacts "+ conatactData
 
        res.status(200).json(saveContact)
    } catch (err) {
        console.log("from API error", err)
        res.status(400).json({ message: 'Something went wrong' });
    }
  }

Это удаляет контакт

Запустите это: npm run dev, и у вас должен быть работающий пример на: localhost:3000.

Теперь это ТУРФ!

Подождите, мне нужно перезарядиться, я имею в виду, что он работал без ошибок, я должен быть «Богом программирования»…

Ну это ложь! Я плакала, жалела о своем выборе, смотрела Youtube, заходила на Stackoverflow, и даже пришлось искать дискорд-канал Nextjs, чтобы все заработало… Никто не делится своими неудачами в сети…

Теперь все работает, давайте подключим сторону Flutter к нашему приложению Next.js.

Создайте новое приложение Flutter Кстати, я использовал VS Code для Next и Android Studio для Flutter. Я имею в виду, что хочу нагрузить свой ноутбук! Как я уже сказал, это на самом деле не учебник, я просто показываю вам, что я сделал, чтобы вы были впечатлены и бросили немного… или, может быть, нет, просто чтобы внести свой вклад в сообщество.

Теперь мне не нужно просматривать различные экраны, проверять Github и, пожалуйста, помечать: Flutter и Nextjs, я должен сказать следующее: localhost не будет работать, поэтому вам нужно получить IPv4 вашего компьютера и используйте его.

Так что да, я знаю, что не делал часть обновления, я имею в виду, что именно поэтому мы делаем открытый исходный код. Так почему бы не разветвить проект и не добавить это? Хм…

В любом случае, спасибо за чтение и просмотр, не забудьте поставить лайк и, возможно, поделиться!