Rumah > hujung hadapan web > tutorial js > Membina Penjadual Tersuai Menggunakan React dan Supabase

Membina Penjadual Tersuai Menggunakan React dan Supabase

Susan Sarandon
Lepaskan: 2024-12-18 07:08:15
asal
304 orang telah melayarinya

pengenalan

Penjadualan ialah salah satu ciri kritikal aplikasi moden. Ia boleh membolehkan kami menjalankan tugas berkala yang boleh diautomasikan. Tugas seperti menghantar peringatan, menjadualkan siaran, mengemas kini data atau mengautomasikan aliran kerja.

Jadi, Dalam artikel ini, kami akan membina penjadual untuk menyiarkan artikel di dev.to. Walaupun, dev.to mempunyai ciri penjadualan tetapi kami akan melaksanakannya mengikut cara kami, yang boleh digunakan untuk membina sebarang jenis aplikasi penjadual.

Jadi, mari kita mulakan.

Timbunan Teknologi

Kami akan menggunakan timbunan teknologi berikut:

  • React: Kami akan menggunakan React, terutamanya ViteJS dengan React untuk membina fronted.
  • Supabase: Ia menyediakan penyelesaian semua-dalam-satu untuk membina aplikasi. Ia menyediakan pangkalan data, pengesahan, storan, fungsi tepi dan banyak lagi. Kami akan menggunakan yang berikut dari Supbase:
    • Pangkalan data: Ini digunakan untuk menyimpan maklumat artikel dan jadual masa.
    • Cron Job: Untuk menjalankan secara berkala untuk memanggil fungsi Edge
    • Fungsi Tepi: Ini akan menyemak sama ada mana-mana artikel mempunyai masa semasa sebagai masa yang dijadualkan. Jika kemudian ia akan menyiarkan artikel itu.

Itu sudah cukup untuk membina aplikasi penjadual dengan mudah.

Bekerja pada Aplikasi

Mari kita bincangkan cara aplikasi berfungsi, yang menjadikannya agak mudah untuk memahami aliran aplikasi. Inilah alirannya satu persatu:

  1. Menambah artikel pada pangkalan data melalui bahagian hadapan.
  2. Tugas Cron akan dijalankan setiap minit untuk memanggil fungsi tepi.
  3. Fungsi tepi akan dilaksanakan untuk menyemak masa semasa seperti yang dijadualkan. Jika ada artikel akan siarkan artikel tersebut.
  4. Data artikel dalam jadual siaran akan dikemas kini. # Membina Bahagian Hadapan

Halaman depan bangunan menjadi senyap kebelakangan ini dengan banyak AI generatif. Salah satu AI yang akan kami gunakan ialah bolt.new. Kenapa bolt.new? Ia boleh menjana aplikasi React lengkap dengan kebergantungan dan semua konfigurasi seperti tailwindcss. Anda boleh terus mengedit artikel menggunakan StackBlitz dan juga menggunakan aplikasi. Jika anda memerlukan anda boleh memuat turun kod untuk dijalankan secara setempat. Perkara bonus ialah ia berintegrasi dengan Supabase dengan agak baik supaya anda boleh menjana aplikasi React yang berfungsi dengan penyepaduan Supbase.

Saya telah menggunakannya untuk menjana bahagian hadapan. Berikut adalah semua halaman.

App.tsx

Ini akan mengendalikan halaman untuk memaparkan komponen dan menyediakan halaman pendaratan.

    function App() {
      const [posts, setPosts] = useState<ScheduledPost[]>([]);
      const handleSchedulePost = async (data: CreatePostData) => {
        // In a real app, this would make an API call to your edge function
        const newPost: ScheduledPost = {
          content: data.content,
          scheduled_time: data.scheduledTime,
          status: 'pending',
          title: data.title,
          tags: data.tags
        };
        const { error } = await supabase
      .from('scheduled_posts')
      .insert(newPost)
      if (error){
        alert(`Erorr: ${error}`)
        return
      }
        // setPosts((prev) => [...prev, newPost]);
      };
      const fetchScheduedPost = async () => {
        const { data, error } = await supabase
      .from('scheduled_posts')
      .select()
      if(error){
        alert(`Erorr Fetching Data: ${error}`)
        return
      }
      setPosts(data)
      } 
      useEffect(() => {
        fetchScheduedPost()
      },[])
      return (
        <div className="min-h-screen bg-gray-50">
          <header className="bg-white shadow-sm">
            <div className="max-w-4xl mx-auto px-4 py-4">
              <div className="flex items-center gap-2">
                <Newspaper className="h-8 w-8 text-blue-500" />
                <h1 className="text-xl font-bold text-gray-900">Dev.to Post Scheduler</h1>
              </div>
            </div>
          </header>
          <main className="max-w-4xl mx-auto px-4 py-8">
            <div className="grid gap-8 md:grid-cols-2">
              <div>
                <h2 className="text-xl font-semibold text-gray-800 mb-4">Schedule New Post</h2>
                <PostForm onSubmit={handleSchedulePost} />
              </div>
              <div>
                <ScheduledPosts posts={posts} />
              </div>
            </div>
          </main>
        </div>
      );
    }
    export default App;
Salin selepas log masuk
Salin selepas log masuk

SchudledPost.tsx

Ini memaparkan artikel yang dijadualkan.

    const StatusIcon = ({ status }: { status: ScheduledPost['status'] }) => {
      switch (status) {
        case 'posted':
          return <CheckCircle className="h-5 w-5 text-green-500" />;
        case 'failed':
          return <XCircle className="h-5 w-5 text-red-500" />;
        default:
          return <Clock3 className="h-5 w-5 text-yellow-500" />;
      }
    };
    export function ScheduledPosts({ posts }: ScheduledPostsProps) {
      return (
        <div className="space-y-4">
          <h2 className="text-xl font-semibold text-gray-800">Scheduled Posts</h2>
          {posts.length === 0 ? (
            <p className="text-gray-500 text-center py-8">No scheduled posts yet</p>
          ) : (
            <div className="space-y-4">
              {posts.map((post, index) => (
                <div
                  key={index}
                  className="bg-white p-4 rounded-lg shadow-md border border-gray-100"
                >
                  <div className="flex items-start justify-between">
                    <div className="flex-1">
                      <p className="text-gray-800 mb-2">{post.title}</p>
                      <div className="flex items-center gap-4 text-sm text-gray-500">
                        <div className="flex items-center gap-1">
                          <Calendar className="h-4 w-4" />
                          {new Date(post.scheduled_time).toLocaleDateString()}
                        </div>
                        <div className="flex items-center gap-1">
                          <Clock className="h-4 w-4" />
                          {new Date(post.scheduled_time).toLocaleTimeString()}
                        </div>
                      </div>
                    </div>
                    <StatusIcon status={post.status} />
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      );
    }
Salin selepas log masuk
Salin selepas log masuk

PostForm.tsx

Ini akan mengendalikan borang di mana pengguna boleh memberikan maklumat tentang artikel.

    function App() {
      const [posts, setPosts] = useState<ScheduledPost[]>([]);
      const handleSchedulePost = async (data: CreatePostData) => {
        // In a real app, this would make an API call to your edge function
        const newPost: ScheduledPost = {
          content: data.content,
          scheduled_time: data.scheduledTime,
          status: 'pending',
          title: data.title,
          tags: data.tags
        };
        const { error } = await supabase
      .from('scheduled_posts')
      .insert(newPost)
      if (error){
        alert(`Erorr: ${error}`)
        return
      }
        // setPosts((prev) => [...prev, newPost]);
      };
      const fetchScheduedPost = async () => {
        const { data, error } = await supabase
      .from('scheduled_posts')
      .select()
      if(error){
        alert(`Erorr Fetching Data: ${error}`)
        return
      }
      setPosts(data)
      } 
      useEffect(() => {
        fetchScheduedPost()
      },[])
      return (
        <div className="min-h-screen bg-gray-50">
          <header className="bg-white shadow-sm">
            <div className="max-w-4xl mx-auto px-4 py-4">
              <div className="flex items-center gap-2">
                <Newspaper className="h-8 w-8 text-blue-500" />
                <h1 className="text-xl font-bold text-gray-900">Dev.to Post Scheduler</h1>
              </div>
            </div>
          </header>
          <main className="max-w-4xl mx-auto px-4 py-8">
            <div className="grid gap-8 md:grid-cols-2">
              <div>
                <h2 className="text-xl font-semibold text-gray-800 mb-4">Schedule New Post</h2>
                <PostForm onSubmit={handleSchedulePost} />
              </div>
              <div>
                <ScheduledPosts posts={posts} />
              </div>
            </div>
          </main>
        </div>
      );
    }
    export default App;
Salin selepas log masuk
Salin selepas log masuk

Fungsi Tepi

Fungsi Tepi ialah fungsi TypeScript sebelah pelayan, diedarkan secara global di tepi—berdekatan dengan pengguna anda. Ia boleh digunakan untuk mendengar webhooks atau menyepadukan projek Supabase anda dengan pihak ketiga seperti Stripe. Fungsi Edge dibangunkan menggunakan Deno.

Untuk menjalankan dan menggunakan fungsi tepi secara setempat, anda perlu mempunyai yang berikut:

  • Supbase CLI: Anda boleh memasang CLI secara setempat menggunakan panduan ini. Ia mudah hanya menggunakan npm dan npx.
  • Desktop Docker: Pasang desktop docker dari sini.

Jadi, selepas memasang ini, anda boleh menggunakan direktori kod bahagian hadapan anda atau yang lain untuk mencipta Fungsi Supabase Edge.

Jalankan arahan di bawah untuk memulakan projek supabase:

    const StatusIcon = ({ status }: { status: ScheduledPost['status'] }) => {
      switch (status) {
        case 'posted':
          return <CheckCircle className="h-5 w-5 text-green-500" />;
        case 'failed':
          return <XCircle className="h-5 w-5 text-red-500" />;
        default:
          return <Clock3 className="h-5 w-5 text-yellow-500" />;
      }
    };
    export function ScheduledPosts({ posts }: ScheduledPostsProps) {
      return (
        <div className="space-y-4">
          <h2 className="text-xl font-semibold text-gray-800">Scheduled Posts</h2>
          {posts.length === 0 ? (
            <p className="text-gray-500 text-center py-8">No scheduled posts yet</p>
          ) : (
            <div className="space-y-4">
              {posts.map((post, index) => (
                <div
                  key={index}
                  className="bg-white p-4 rounded-lg shadow-md border border-gray-100"
                >
                  <div className="flex items-start justify-between">
                    <div className="flex-1">
                      <p className="text-gray-800 mb-2">{post.title}</p>
                      <div className="flex items-center gap-4 text-sm text-gray-500">
                        <div className="flex items-center gap-1">
                          <Calendar className="h-4 w-4" />
                          {new Date(post.scheduled_time).toLocaleDateString()}
                        </div>
                        <div className="flex items-center gap-1">
                          <Clock className="h-4 w-4" />
                          {new Date(post.scheduled_time).toLocaleTimeString()}
                        </div>
                      </div>
                    </div>
                    <StatusIcon status={post.status} />
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      );
    }
Salin selepas log masuk
Salin selepas log masuk

Arahan di bawah boleh digunakan untuk mencipta fungsi Edge

    export function PostForm({ onSubmit }: PostFormProps) {
      const [content, setContent] = useState('');
      const [title, setTitle] = useState('');
      const [tags, setTags] = useState<string[]>(['javascript', 'react']);
      const [scheduledTime, setScheduledTime] = useState('');
      const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        onSubmit({ content, title, scheduledTime, tags });
        setContent('');
        setTitle('');
        setScheduledTime('');
        setTags([]);
      };
      const handleTagChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
        const selectedOptions = Array.from(e.target.selectedOptions);
        const selectedTags = selectedOptions.map(option => option.value);
        if(tags.length<4){
    setTags(prevTags => {
          const newTags = selectedTags.filter(tag => !prevTags.includes(tag));
          return [...prevTags, ...newTags];
        });
        }

      };
      const removeTag = (tagToRemove: string) => {
        setTags(tags.filter(tag => tag !== tagToRemove));
      };
      return (
        <form onSubmit={handleSubmit} className="space-y-4 bg-white p-6 rounded-lg shadow-md">
          <div>
            <label htmlFor="title" className="block text-sm font-medium text-gray-700 mb-2">
              Post Title
            </label>
            <input
              type="text"
             >



<p>I will provide the whole code as a GitHub repository at the end. </p>

<p>Now, let’s look at Supbase Integration.</p>

<h2>
  
  
  Supabase
</h2>

<p>First create an account on supabase, if you don’t have one. You can look at this article to get information about the creating an account on Supbase, Using ChatGPT with Your Own Data using LangChain and Supabase.</p>

<p>Create the table scheduled_post. You can use the below SQL code to run in the SQL Editor to create the table or you can create the table with Table Editor.<br>
</p>

<pre class="brush:php;toolbar:false">    create table
      public.scheduled_posts (
        id serial not null,
        content text not null,
        scheduled_time timestamp with time zone not null,
        status text null default 'pending'::text,
        created_at timestamp without time zone null default now(),
        title character varying null,
        devto_article_id character varying null,
        posted_at character varying null,
        tags character varying[] null,
        error_message character varying null,
        constraint scheduled_posts_pkey primary key (id)
      ) tablespace pg_default;
    create index if not exists idx_scheduled_time_status on public.scheduled_posts using btree (scheduled_time, status) tablespace pg_default;
Salin selepas log masuk

Arahan di atas akan mencipta fungsi direktori/xscheduler di dalam supabase. Di sana anda boleh mencari index.ts. Fungsi tepi menggunakan persekitaran Deno.

Kod di bawah adalah untuk fungsi tepi:

    npx supabase init
Salin selepas log masuk

Untuk ENV seperti SUPABASE_URL dan SUPABASE_SERVICE_ROLE_KEY tersedia secara automatik untuk anda. Untuk DEVTO_ACCESS_TOKEN, anda boleh menjananya dari sini dan pergi ke Tetapan Projek → Fungsi Tepi untuk menambah token. Token ini akan tersedia dalam persekitaran Deno.

Anda boleh menggunakan panduan ini untuk menggunakan fungsi tepi, yang diperlukan.

Cron Job

Supbase mengemas kini fungsi kerja Cron baru-baru ini. Kini anda boleh menggunakan papan pemuka untuk membuat kerja jagung sebelum ini anda perlu menulis kod untuk itu. Anda boleh membuat kerja yang boleh menjalankan perkara berikut:

  • SQL Snippet
  • Fungsi Pangkalan Data
  • Permintaan HTTP
  • Fungsi Tepi Supbase

Kami akan menggunakan Fungsi Edge, Anda boleh menambah butiran fungsi Edge seperti nama dan Kebenaran dengan kekunci Anon sebagai Token Pembawa.

Building a Custom Scheduler Using React and Supabase

Kerja Permohonan

Sekarang, bahawa kita telah mencipta aplikasi, mari kita lihat kerja sekarang. Jalankan bahagian hadapan dengan arahan di bawah:

    supabase functions new xscheduler
Salin selepas log masuk

Building a Custom Scheduler Using React and Supabase

Tambahkan butiran seperti Tajuk, Kandungan, Masa dan Teg. Setelah ditambah klik pada Jadual Post. Tugas cron akan dijalankan setiap minit setelah masa yang dijadualkan artikel sepadan dengan masa semasa. Ia akan disiarkan.

Artikel akan disiarkan pada dev.to apabila julat masa sepadan.

Building a Custom Scheduler Using React and Supabase

Ciri-ciri Tambahan

Menggunakan teknik di atas, anda boleh membina aplikasi penjadual untuk apa-apa sahaja seperti X, Instagram, LinkedIn, dll. Anda boleh mengusahakannya dan menambah fungsi seperti berikut:

  • Imej: Gunakan storan supabase untuk memuat naik dan mengambil imej untuk lakaran kenit.
  • Fungsi tepi digunakan daripada SQL: Anda boleh menjadikannya lebih cekap dengan memanggil fungsi tepi daripada coretan SQL atau fungsi Pangkalan Data. Ini supaya hanya apabila artikel sepadan dengan masa semasa, fungsi tepi digunakan.

Anda boleh melihat ke dalam kod projek ini di GitHub di sini.

Kesimpulan

Membuat aplikasi penjadual memudahkan tugas mengautomasikan seperti menyiarkan artikel, menghantar peringatan dan mengurus aliran kerja. Menggunakan React untuk bahagian hadapan dan Supabase untuk bahagian belakang, kami membina penyelesaian berskala yang memanfaatkan pangkalan data, tugas cron dan fungsi tepi. Pendekatan ini boleh disesuaikan untuk pelbagai kes penggunaan, membolehkan automasi yang cekap. Dengan alatan ini, anda dilengkapi untuk membina aplikasi penjadual berkuasa yang disesuaikan dengan keperluan anda.

Saya harap artikel ini telah memberikan anda pemahaman tentang tugas cron. Terima kasih kerana membaca artikel.

Atas ialah kandungan terperinci Membina Penjadual Tersuai Menggunakan React dan Supabase. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan