En el archivo ReplaceVideosPage.tsx hay un botón que dice "Replace all playlist items", cuando se presiona se activa una API, quiero que el texto del <pre> se muestre el texto "`${videoIds.length - failedItems} video(s) added to playlist successfully.`" de la respuesta del archivo "src\services\addVideosToPlaylist.js"

// src\features\playlist-management\components\ReplaceVideosPage.tsx

import { useEffect, useState } from "react";
import extractIDsFromUrls from "../../../services/extractIDsFromUrls";
import CustomButton from "./CustomButton";
import CustomTextarea from "./CustomTextarea";
import CustomInput from "./CustomInput";

const ReplaceVideosPage = () => {
  const [youtubeUrls, setYoutubeUrls] = useState<string>("");
  const [videoIds, setVideoIds] = useState<string[]>([]);
  const [customPlaylistID, setCustomPlaylistId] = useState<string>("");
  const [isLoading, setIsLoading] = useState<boolean>(false);

  const replacePlaylistData = async () => {
    try {
      setIsLoading(true);
      const responseGet = await fetch(`/api/playlists/${customPlaylistID}`);

      if (!responseGet.ok) {
        throw new Error(
          `Get Playlist API request failed: ${responseGet.status}`
        );
      }

      const dataGet = await responseGet.json();
      const allIDs = dataGet.allItems.map((item: { id: string }) => item.id);
      const IDsToAdd = videoIds.filter((id) => !allIDs.includes(id));
      const IDsToRemove = allIDs.filter((id: string) => !videoIds.includes(id));

      const responseCreate = await fetch(
        `/api/createPlaylist?newItems=${encodeURIComponent(
          JSON.stringify(IDsToAdd)
        )}&customPlaylistId=${customPlaylistID}`
      );

      if (!responseCreate.ok) {
        throw new Error(
          `Create Playlist API request failed: ${responseCreate.status}`
        );
      }

      const responseDelete = await fetch(
        `/api/deleteFromPlaylist?newItems=${encodeURIComponent(
          JSON.stringify(IDsToRemove)
        )}&customPlaylistId=${customPlaylistID}`
      );

      if (!responseDelete.ok) {
        throw new Error(
          `Delete Playlist API request failed: ${responseDelete.status}`
        );
      }

      setIsLoading(false);
    } catch (error) {
      console.error("Error processing Replace Playlist API:", error);
    }
  };

  useEffect(() => {
    setVideoIds(extractIDsFromUrls(youtubeUrls));
  }, [youtubeUrls]);

  return (
    <main className="w-full max-w-lg mx-auto my-8 flex flex-col gap-4">
      <CustomInput
        title="Required Playlist ID*"
        onChangeHandler={setCustomPlaylistId}
        inputValue={customPlaylistID}
      />
      <CustomTextarea
        onChangeHandler={setYoutubeUrls}
        placeholder="Enter youtube links..."
        textareaValue={youtubeUrls}
      />
      {videoIds.length > 0 && (
        <>
          <p># ID: {videoIds.length}</p>
          <CustomButton
            buttonText={
              isLoading ? "Cargando..." : "Replace all playlist items"
            }
            isLoading={isLoading}
            onClickHandler={replacePlaylistData}
          />
        </>
      )}
      <div className="bg-gray-300 p-4 rounded-md">
        <pre className="text-sm font-mono">
          <code className="block">Tu código aquí...</code>
        </pre>
      </div>
    </main>
  );
};

export default ReplaceVideosPage;

// src\pages\api\createPlaylist.ts

import { google } from "googleapis";
import { promises as fs } from "fs";
import {
  CLIENT_ID,
  CLIENT_SECRET,
  REDIRECTION_URI,
} from "../../models/credentials";
import createPlaylist from "../../services/createPlaylist";

const oAuth2Client: any = new google.auth.OAuth2(
  CLIENT_ID,
  CLIENT_SECRET,
  REDIRECTION_URI
);

export default async function handler(req: any, res: any) {
  try {
    const {
      newItems,
      customPlaylistId,
    }: { newItems: string; customPlaylistId?: string } = req.query;

    const token: any = await fs.readFile("token.json");
    const parsedToken = JSON.parse(token);
    oAuth2Client.setCredentials(parsedToken);

    const newPlaylistId = await createPlaylist({
      auth: oAuth2Client,
      newItems,
      customPlaylistId,
    });

    res
      .status(200)
      .json({ message: "Playlist created successfully", newPlaylistId });
  } catch (error) {
    console.error("Error:", error);
    res.status(500).json({ error: "Internal Server Error" });
  }
}

// src\services\createPlaylist.ts

import { google } from "googleapis";
import addVideosToPlaylist from "./addVideosToPlaylist";

interface CreatePlaylistData {
  auth: any;
  newItems: string;
  customPlaylistId?: string;
}

async function createPlaylist({
  auth,
  newItems,
  customPlaylistId,
}: CreatePlaylistData): Promise<string> {
  const youtube: any = google.youtube({ version: "v3", auth });

  try {
    let playlistId: string;
    let videoIds: string[] = JSON.parse(newItems);

    if (customPlaylistId) {
      playlistId = customPlaylistId;
      console.log("Using custom playlist ID:", playlistId);

      const getPlaylistData = async (): Promise<string[]> => {
        try {
          const response = await fetch(
            `http://localhost:3000/api/playlists/${playlistId}`
          );

          if (!response.ok) {
            throw new Error(
              `API request failed with status ${response.status}`
            );
          }

          const data = await response.json();
          const allIDs = data.allItems.map((item: any) => item.id);

          videoIds = videoIds.filter((videoId) => !allIDs.includes(videoId));
          return videoIds;
        } catch (error) {
          console.error("Error fetching playlist data:", error);
          return [];
        }
      };

      videoIds = await getPlaylistData();
    } else {
      const res = await youtube.playlists.insert({
        part: ["snippet,status"],
        resource: {
          snippet: {
            title: "Música",
            description: "Descripción",
            tags: ["Music"],
            defaultLanguage: "es_MX",
          },
          status: {
            privacyStatus: "unlisted",
          },
        },
      });

      playlistId = res.data.id;
      console.log("Playlist created:", playlistId);
    }

    await addVideosToPlaylist(auth, playlistId, videoIds);

    return playlistId;
  } catch (err) {
    console.error("Error creating playlist:", err);
    throw err;
  }
}

export default createPlaylist;


//  src\services\addVideosToPlaylist.js

const { google } = require("googleapis");

async function addVideosToPlaylist(auth, playlistId, videoIds) {
  const youtube = google.youtube({
    version: "v3",
    auth,
  });

  console.log(`Adding ${videoIds.length} videos to playlist.`);
  let failedItems = 0;
  let countIds = 0;

  for (const videoId of videoIds) {
    countIds++;
    try {
      await youtube.playlistItems.insert({
        part: ["snippet"],
        resource: {
          snippet: {
            playlistId: playlistId,
            resourceId: {
              kind: "youtube#video",
              videoId: videoId,
            },
          },
        },
      });
      console.log(`Added ${countIds} of ${videoIds.length}: ${videoId}`);
    } catch (err) {
      console.error(`Error ${countIds} of ${videoIds.length}: ${videoId}`);
      failedItems++;
    }
  }

  console.log(
    `${videoIds.length - failedItems} video(s) added to playlist successfully.`
  );
  failedItems && console.log(`${failedItems} video(s) failed.`);
}

module.exports = addVideosToPlaylist;