Skip to content

Commit

Permalink
Merge pull request #40 from frankduandou/20240628_generate-content
Browse files Browse the repository at this point in the history
generate content_headlines
  • Loading branch information
keyskull authored Jun 30, 2024
2 parents 9a2480a + 2008527 commit 962cd9f
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 55 deletions.
8 changes: 6 additions & 2 deletions app/(root)/group/manage/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -28,6 +29,7 @@ export default function Page({
const [campaignId, setCampaignId] = useState<string>('');
const [campaignName, setCampaignName] = useState<string>('');
const [adGroupAll, setAdGroupAll] = useState<any[]>([]);
const [showLoading, setShowLoading] = useState(true);
useEffect(() => {
const message = Cookies.get('notification_create_adgroup');
function showToast() {
Expand Down Expand Up @@ -59,13 +61,14 @@ export default function Page({
}
}, []);
const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
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);
Expand Down Expand Up @@ -105,7 +108,8 @@ return (
<div className="mt-4 flex items-center justify-center gap-2 md:mt-8">
<Search placeholder="Search ad..." />
</div>
<AdGroupTable query={query} currentPage={currentPage} campaignId={campaignId} campaignName={campaignName}/>
{showLoading && <Spinner label="Loading ad groups..." color="default" />}
{!showLoading && <AdGroupTable query={query} currentPage={currentPage} campaignId={campaignId} campaignName={campaignName}/>}
<div className="mt-5 flex w-full justify-center">
<Pagination totalPages={totalPages} />
</div>
Expand Down
162 changes: 130 additions & 32 deletions components/ui/form-create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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' }),
Expand All @@ -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<any[]>([]);
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formElement = e.currentTarget;
Expand Down Expand Up @@ -77,6 +88,13 @@ const handleChange = (event: React.ChangeEvent<HTMLInputElement | HTMLSelectElem
...prevErrors,
[name]: '',
}));
// Generate headline button is showed when headline1 is filled
if(name === 'headline1' && value !== ''){
setShowGenerateHeadline(true)
}
else if(name === 'headline1' && value === ''){
setShowGenerateHeadline(false);
}
};
const handleDateChange = (name: string, date: CalendarDate | null) => {
setFormData((prevData) => ({
Expand All @@ -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
Expand Down Expand Up @@ -134,6 +153,7 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
})
}

//about adding headlines
const handleAddHeadlines = () =>{
if (!addHeadline.showHeadline4 && !addHeadline.showHeadline5){
setHeadlines(() => {
Expand All @@ -155,8 +175,8 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
}
};

//about image upload
const [uploadedFile, setUploadedFile] = useState<any | null>(null);

const handleUploadComplete = (file: any) => {
setUploadedFile(file);
setFormData((prevData) => ({
Expand All @@ -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 (
<form onSubmit={handleSubmit}>
<header className="flex items-center justify-between px-6 py-4 bg-gray-900 text-white">
Expand All @@ -179,7 +241,7 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
</div>
<div className="mt-6 flex justify-end gap-4">
<Link
href="/"
href="/manage"
className="flex h-10 items-center rounded-lg bg-gray-100 px-4 text-sm font-medium text-gray-600 transition-colors hover:bg-gray-200"
>
Cancel
Expand Down Expand Up @@ -224,7 +286,6 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
</label>
</div>
<div className="md:w-3/4 inline-flex">
<div className='md:w-3/4'>
<input id="adUrl"
name="url"
placeholder="https://"
Expand All @@ -233,12 +294,6 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
type="text"
value={formData.url}
onChange={handleChange} />
</div>
<div className='md:w-1/4'>
<Button className='float-right' color="primary" type='button'>
Generate info below
</Button>
</div>
</div>
</div>
<div className="md:flex md:items-center mb-6">
Expand Down Expand Up @@ -442,7 +497,13 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
</label>
</div>
<div className="md:w-3/4">
<input id="adHeadline2" name="headline2" placeholder="Enter the 2nd headline" 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" />
<input id="adHeadline2"
name="headline2"
placeholder="Enter the 2nd headline"
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.headline2}
/>
</div>
</div>
<div className="md:flex md:items-center mb-6">
Expand All @@ -452,7 +513,12 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
</label>
</div>
<div className="md:w-3/4">
<input id="adHeadline3" name="headline3" placeholder="Enter the 3rd headline" 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" />
<input id="adHeadline3"
name="headline3"
placeholder="Enter the 3rd headline"
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.headline3}/>
</div>
</div>
{addHeadline.showHeadline4 && (
Expand All @@ -463,7 +529,12 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
</label>
</div>
<div className="md:w-3/4">
<input id="adHeadline4" name="headline4" placeholder="Enter the 4th headline" 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" />
<input id="adHeadline4"
name="headline4"
placeholder="Enter the 4th headline"
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.headline4}/>
</div>
</div>)
}
Expand All @@ -475,28 +546,61 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
</label>
</div>
<div className="md:w-3/4">
<input id="adHeadline5" name="headline5" placeholder="Enter the 5th headline" 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" />
<input id="adHeadline5"
name="headline5"
placeholder="Enter the 5th headline"
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.headline5}/>
</div>
</div>)
}
{addHeadline.showAddHeadlineButton && (

<div className="md:flex md:items-center mb-6">
<div className="md:w-1/4"> </div>
<div className="md:w-3/4">
<Button className='float-left' color="primary" type='button' onClick={handleAddHeadlines}>
Add new headline
</Button>
</div>
</div> )
}
<div className="flow-root">
{addHeadline.showAddHeadlineButton && <Button className='float-left' color="primary" type='button' onClick={handleAddHeadlines}>
Add new headline
</Button>}
{showGenerateHeadline && <Button className='float-right' color="primary" type='button' onPress={onOpen} onClick={handleGenerateHeadlines}>
Generate headlines
</Button>
}
<Modal size="4xl" isOpen={isOpen} onOpenChange={onOpenChange} placement='top' classNames={{base:"bg-white"}}>
<ModalContent>
{(onClose) => (
<>
<ModalHeader className="flex flex-col gap-1">Do you accept the following generated headlines?</ModalHeader>
<ModalBody>
{showLoading && <Spinner label="Generating headlines..." color="default" />}
{!showLoading && generatedHeadline.map((item:generate_content_result) => (
<div key={item.index}><label>Headline{item.index}:&nbsp;&nbsp;</label>{item.data}</div>
))}
</ModalBody>
<ModalFooter>
<Button color="danger" variant="light" onPress={onClose} className='flex h-10 items-center rounded-lg bg-gray-100 px-4 text-sm font-medium text-gray-600 transition-colors hover:bg-gray-200'>
No
</Button>
<Button color="primary" onPress={()=>AcceptContentHandler()} className='flex h-10 items-center rounded-lg bg-blue-600 px-4 text-sm font-medium text-white transition-colors hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600'>
Yes
</Button>
</ModalFooter>
</>
)}
</ModalContent>
</Modal>
</div>
</div>
</div>

<div className="md:flex md:items-center mb-6">
<div className="md:w-1/4">
<label className="block text-gray-500 font-bold mb-1 md:mb-0 pr-4" htmlFor="adTargetAudience">
Target Audience*
</label>
</div>
<div className="md:w-3/4 inline-flex">
<div className='md:w-3/4'>
<input id="adTargetAudience"
name="target"
aria-describedby="target-error"
Expand All @@ -505,13 +609,7 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
type="text"
value={formData.target}
onChange={handleChange}
/>
</div>
<div className='md:w-1/4'>
<Button className='float-right' color="primary" type='button'>
ReGenerate
</Button>
</div>
/>
</div>
</div>
<div className="md:flex md:items-center mb-6">
Expand Down
20 changes: 3 additions & 17 deletions components/ui/form-update.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
</div>
<div className="mt-6 flex justify-end gap-4">
<Link
href="/"
href="/manage"
className="flex h-10 items-center rounded-lg bg-gray-100 px-4 text-sm font-medium text-gray-600 transition-colors hover:bg-gray-200"
>
Cancel
Expand Down Expand Up @@ -236,21 +236,14 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
</label>
</div>
<div className="md:w-3/4 inline-flex">
<div className='md:w-3/4'>
<input id="adUrl"
name="url"
placeholder="https://"
aria-describedby="url-error"
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} />
</div>
<div className='md:w-1/4'>
<Button className='float-right' color="primary" type='button'>
Generate info below
</Button>
</div>
onChange={handleChange} />
</div>
</div>
<div className="md:flex md:items-center mb-6">
Expand Down Expand Up @@ -508,7 +501,6 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
</label>
</div>
<div className="md:w-3/4 inline-flex">
<div className='md:w-3/4'>
<input id="adTargetAudience"
name="target"
aria-describedby="target-error"
Expand All @@ -517,13 +509,7 @@ const handleDateChange = (name: string, date: CalendarDate | null) => {
type="text"
value={formData.target}
onChange={handleChange}
/>
</div>
<div className='md:w-1/4'>
<Button className='float-right' color="primary" type='button'>
ReGenerate
</Button>
</div>
/>
</div>
</div>
<div className="md:flex md:items-center mb-6">
Expand Down
Loading

0 comments on commit 962cd9f

Please sign in to comment.