From 20085276aa6e6a43fce265c94833bcdaa4819988 Mon Sep 17 00:00:00 2001 From: frankduandou Date: Sat, 29 Jun 2024 19:30:39 -0400 Subject: [PATCH] generate content_headlines --- app/(root)/group/manage/page.tsx | 8 +- components/ui/form-create.tsx | 162 +++++++++++++++++++++++++------ components/ui/form-update.tsx | 20 +--- lib/api.ts | 16 ++- lib/definitions.ts | 8 +- 5 files changed, 159 insertions(+), 55 deletions(-) diff --git a/app/(root)/group/manage/page.tsx b/app/(root)/group/manage/page.tsx index 9d82598..0964cf8 100644 --- a/app/(root)/group/manage/page.tsx +++ b/app/(root)/group/manage/page.tsx @@ -10,6 +10,7 @@ import 'react-toastify/dist/ReactToastify.css'; import Cookies from 'js-cookie'; import { toast } from 'react-toastify'; import AdGroupTable from '@/components/ui/ad-group-table'; +import {Spinner} from "@nextui-org/react"; export default function Page({ searchParams, @@ -28,6 +29,7 @@ export default function Page({ const [campaignId, setCampaignId] = useState(''); const [campaignName, setCampaignName] = useState(''); const [adGroupAll, setAdGroupAll] = useState([]); + const [showLoading, setShowLoading] = useState(true); useEffect(() => { const message = Cookies.get('notification_create_adgroup'); function showToast() { @@ -59,13 +61,14 @@ export default function Page({ } }, []); const handleChange = (event: React.ChangeEvent) => { + setShowLoading(true); const selectedOption = event.target.selectedOptions[0]; const campaignName = selectedOption.value; const campaignId = selectedOption.getAttribute('data-id') as string; if(campaignId !== ''){ setCampaignId(campaignId); setAdGroupAll([]); - fetchGroupList(campaignId).then(data => setAdGroupAll(data.result)); + fetchGroupList(campaignId).then(data => setAdGroupAll(data.result)).finally(() => setShowLoading(false)); } if(campaignName !== ''){ setCampaignName(campaignName); @@ -105,7 +108,8 @@ return (
- + {showLoading && } + {!showLoading && }
diff --git a/components/ui/form-create.tsx b/components/ui/form-create.tsx index 633e98f..9ab073d 100644 --- a/components/ui/form-create.tsx +++ b/components/ui/form-create.tsx @@ -8,9 +8,12 @@ import { z } from "zod"; import { parseDate, DateValue, CalendarDate } from '@internationalized/date'; import { Button, Textarea } from '@nextui-org/react'; import { assembleAd } from "@/lib/utils"; -import { createAdvertisement } from "@/lib/api"; +import { GenerateContent, createAdvertisement } from "@/lib/api"; import Cookies from "js-cookie"; import { useRouter } from 'next/navigation'; +import { generate_content_result } from "@/lib/definitions"; +import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, useDisclosure} from "@nextui-org/react"; +import {Spinner} from "@nextui-org/react"; const schema = z.object({ name: z.string().min(1, { message: 'Name is required' }), @@ -26,12 +29,20 @@ const schema = z.object({ description: z.string().min(1, { message: 'Description is required' }), image: z.string().min(1, { message: 'Image is required' }), }); - +interface ApiResponse { + result: { + type: string; + result: generate_content_result[]; + }[]; +} export default function Form({ channels }: { channels: any[] }) { - const [formData, setFormData] = useState({ name: '', url: '', location: '', phone: '', channel: '', budget: '', headline1: '', target: '', start: '', end: '', description: '', image:''}); + const [formData, setFormData] = useState({ name: '', url: '', location: '', phone: '', channel: '', budget: '', headline1: '',headline2: '',headline3: '',headline4: '',headline5: '', target: '', start: '', end: '', description: '', image:''}); const [errors, setErrors] = useState<{ [key: string]: string }>({}); const router = useRouter(); + const [showGenerateHeadline, setShowGenerateHeadline] = useState(false); + const [showLoading, setShowLoading] = useState(true); + const [generatedHeadline,setGeneratedHeadline] = useState([]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); const formElement = e.currentTarget; @@ -77,6 +88,13 @@ const handleChange = (event: React.ChangeEvent { setFormData((prevData) => ({ @@ -93,10 +111,11 @@ const handleDateChange = (name: string, date: CalendarDate | null) => { showHeadline5:false, showAddHeadlineButton:true }) + + //about seo keywords const initialSeo = GetInitialSeoKeywords(); const [inputsRecommanded, setInputs] = useState(initialSeo); const [valueSeoInput, setValue] = useState(''); - const [seoButtons, setSeoButtons] = useState({ disableAddButton:true, disableRefreshButton:true @@ -134,6 +153,7 @@ const handleDateChange = (name: string, date: CalendarDate | null) => { }) } + //about adding headlines const handleAddHeadlines = () =>{ if (!addHeadline.showHeadline4 && !addHeadline.showHeadline5){ setHeadlines(() => { @@ -155,8 +175,8 @@ const handleDateChange = (name: string, date: CalendarDate | null) => { } }; + //about image upload const [uploadedFile, setUploadedFile] = useState(null); - const handleUploadComplete = (file: any) => { setUploadedFile(file); setFormData((prevData) => ({ @@ -171,6 +191,48 @@ const handleDateChange = (name: string, date: CalendarDate | null) => { useEffect(() => { console.log('uploaded file updated:', uploadedFile); }, [uploadedFile]); + + //about generate headlines + const handleGenerateHeadlines = async () => { + const headline1 = formData.headline1; + const indexArray = [1,2,3]; + if(addHeadline.showHeadline4){ + indexArray.push(4); + } + if(addHeadline.showHeadline5){ + indexArray.push(5); + } + let gcData ={ + attributes: [{ + index:0, + headline:headline1, + }], + output_type:[{ + index:indexArray, + type: "headline" + }] + } + + const response: ApiResponse = await GenerateContent(gcData).finally(() => { + setShowLoading(false); + }); + const headlineResult = response.result.find(item => item.type === 'headline'); + if (headlineResult && headlineResult.result) { + setGeneratedHeadline(headlineResult.result) + } + }; + //about Modal for generated headlines + const {isOpen, onOpen,onClose, onOpenChange} = useDisclosure(); + const AcceptContentHandler = async () => { + generatedHeadline.map((item:generate_content_result) => { + setFormData((prevData) => ({ + ...prevData, + ["headline"+item.index]: item.data, + })); + }); + setShowGenerateHeadline(false); + onClose(); // Close the modal + }; return (
@@ -179,7 +241,7 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
Cancel @@ -224,7 +286,6 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
-
{ type="text" value={formData.url} onChange={handleChange} /> -
-
- -
@@ -442,7 +497,13 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
- +
@@ -452,7 +513,12 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
- +
{addHeadline.showHeadline4 && ( @@ -463,7 +529,12 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
- +
) } @@ -475,20 +546,54 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
- +
) } - {addHeadline.showAddHeadlineButton && ( +
- -
-
) - } +
+ {addHeadline.showAddHeadlineButton && } + {showGenerateHeadline && + } + + + {(onClose) => ( + <> + Do you accept the following generated headlines? + + {showLoading && } + {!showLoading && generatedHeadline.map((item:generate_content_result) => ( +
{item.data}
+ ))} +
+ + + + + + )} +
+
+
+ + +
-
{ type="text" value={formData.target} onChange={handleChange} - /> -
-
- -
+ />
diff --git a/components/ui/form-update.tsx b/components/ui/form-update.tsx index cb84184..2fdd3dc 100644 --- a/components/ui/form-update.tsx +++ b/components/ui/form-update.tsx @@ -191,7 +191,7 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
Cancel @@ -236,7 +236,6 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
-
{ className="appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-blue-500" type="text" value={formData.url} - onChange={handleChange} /> -
-
- -
+ onChange={handleChange} />
@@ -508,7 +501,6 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
-
{ type="text" value={formData.target} onChange={handleChange} - /> -
-
- -
+ />
diff --git a/lib/api.ts b/lib/api.ts index 3ccf32b..bc603de 100644 --- a/lib/api.ts +++ b/lib/api.ts @@ -4,7 +4,6 @@ const API_CAMPAIGN_URL = API_BASE_URL + '/campaign'; const API_GROUP_URL = API_BASE_URL + '/group'; export const createAdvertisement = async (adData: any) => { - const data = JSON.stringify(adData); const response = await fetch(`${API_BASE_URL}/create`, { method: 'POST', headers: { @@ -69,7 +68,6 @@ export const fetchImage = async (imageId:string) => { }; export const createCampaign = async (campaignData: any) => { - const data = JSON.stringify(campaignData); const response = await fetch(`${API_CAMPAIGN_URL}/create`, { method: 'POST', headers: { @@ -109,7 +107,6 @@ export const fetchCampaignList = async () => { }; export const createGroup = async (groupData: any) => { - const data = JSON.stringify(groupData); const response = await fetch(`${API_GROUP_URL}/create`, { method: 'POST', headers: { @@ -147,3 +144,16 @@ export const fetchGroupList = async (campaignId: string) => { const response = await fetch(`${API_GROUP_URL}/list?campaignId=${campaignId}`); return response.json(); }; + +export const GenerateContent = async (gcData: any) => { + const data = JSON.stringify(gcData); + console.log("gcData",data); + const response = await fetch(`${API_BASE_URL}/ai/generate_content`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(gcData), + }); + return response.json(); + }; \ No newline at end of file diff --git a/lib/definitions.ts b/lib/definitions.ts index 0f2c066..2106ec3 100644 --- a/lib/definitions.ts +++ b/lib/definitions.ts @@ -67,4 +67,10 @@ export type campaign_attribute = { type: string; subtype?: string; value: string; -} \ No newline at end of file +} + +export type generate_content_result={ + index:number; + data:string; +} + \ No newline at end of file