Skip to content

Commit 9638311

Browse files
feat: Add ToolIcon component with image fallback and update tool logo generation logic.
1 parent 2b2ce6d commit 9638311

4 files changed

Lines changed: 273 additions & 164 deletions

File tree

app/(pages)/newtool/page.js

Lines changed: 174 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const AddNewTool = () => {
1111
const router = useRouter();
1212

1313

14-
const [Errors,setErrors] = useState(['Name can\'t be empty','Message cannt be empty'])
14+
const [Errors, setErrors] = useState(['Name can\'t be empty', 'Message cannt be empty'])
1515

1616
const [tools, setTools] = useState([{
1717
name: 'Chat Gpt',
@@ -66,12 +66,12 @@ const AddNewTool = () => {
6666
setTags(tags.filter((tag, i) => i !== index));
6767
};
6868

69-
useEffect(()=>{
69+
useEffect(() => {
7070
setCurrentTool({
7171
...CurrentTool,
7272
tags: tags
7373
})
74-
},[tags])
74+
}, [tags])
7575

7676
useEffect(() => {
7777

@@ -98,18 +98,31 @@ const AddNewTool = () => {
9898
}, [CurrentTool])
9999

100100
useEffect(() => {
101-
102-
if (CurrentTool.link == '') {
103-
setCurrentTool({
104-
...CurrentTool,
105-
image: ''
106-
})
101+
if (!CurrentTool.link) {
102+
setCurrentTool(prev => ({ ...prev, image: '' }));
103+
return;
107104
}
108-
else {
109-
setCurrentTool({
110-
...CurrentTool,
111-
image: 'https://logo.clearbit.com/' + CurrentTool.link
112-
})
105+
106+
try {
107+
let urlString = CurrentTool.link;
108+
if (!/^https?:\/\//i.test(urlString)) {
109+
urlString = 'https://' + urlString;
110+
}
111+
const url = new URL(urlString);
112+
const hostname = url.hostname;
113+
114+
if (hostname) {
115+
let cleanHostname = hostname;
116+
if (cleanHostname.startsWith('www.')) {
117+
cleanHostname = cleanHostname.slice(4);
118+
}
119+
const logoUrl = `https://img.logo.dev/${cleanHostname}?token=live_6a1a28fd-6420-4492-aeb0-b297461d9de2&size=100&retina=true&format=png&theme=dark`;
120+
setCurrentTool(prev => ({ ...prev, image: logoUrl }));
121+
}
122+
} catch (error) {
123+
// Invalid URL, clear image or keep previous? Clearing seems safer for preview.
124+
// But if user is typing, we might not want to flicker too much.
125+
// However, existing logic only set image on link change.
113126
}
114127
}, [CurrentTool.link])
115128

@@ -133,7 +146,7 @@ const AddNewTool = () => {
133146
.then(async response => {
134147

135148
if (response.data.ok) {
136-
149+
137150
router.replace('/submitted')
138151

139152
setCurrentTool({
@@ -155,8 +168,8 @@ const AddNewTool = () => {
155168
})
156169
.catch(error => {
157170
console.error(error);
158-
console.error( error.response);
159-
console.error( error.message);
171+
console.error(error.response);
172+
console.error(error.message);
160173
});
161174
};
162175

@@ -175,164 +188,164 @@ const AddNewTool = () => {
175188
return (
176189

177190
<>
178-
<title>Submit a new Tool - Which AI</title>
179-
<meta name='title' content='Submit a new Tool - Which AI' />
180-
181-
<div className='px-6 lg:px-16 py-12'>
182-
<div className='lg:flex gap-6 w-full'>
183-
184-
<div className='space-y-6 lg:w-2/3'>
185-
186-
<div className='mx-3'>
187-
<h1 className="text-2xl lg:text-4xl text-slate-200 font-bold ">Submit a new AI Tool</h1>
188-
<p className='border-y-[1px] py-4 my-4 border-slate-600 text-slate-400 text-xs lg:text-sm'> Please provide accurate and complete details when submitting your AI tool. Inaccurate or incomplete information may result in your tool not being published on our website. Your attention to detail helps us maintain a high-quality platform.</p>
189-
</div>
190-
191-
<div className="w-full md:w-full px-3 mb-6 md:mb-0">
192-
<label className="block uppercase tracking-wide text-slate-400 text-xs font-bold mb-2" htmlFor="name">
193-
Tool Name<span className='text-red-500'> *</span>
194-
</label>
195-
<input placeholder='Enter name of tool i.e "Chat GPT"'
196-
className="appearance-none block w-full text-slate-300 border border-slate-500 bg-slate-950 rounded py-3 px-4 leading-tight focus:outline-none "
197-
id="name"
198-
name='name'
199-
type="text"
200-
value={CurrentTool.name}
201-
onChange={handleInputChange}
202-
/>
203-
</div>
204-
205-
<div className="w-full md:w-full px-3 mb-6 md:mb-0">
206-
<label className="block uppercase tracking-wide text-slate-400 text-xs font-bold mb-2" htmlFor="category">
207-
Category<span className='text-red-500'> *</span>
208-
</label>
209-
<select
210-
className="appearance-none block w-full text-slate-300 border border-slate-500 bg-slate-950 rounded py-3 px-4 leading-tight focus:outline-none"
211-
id="category"
212-
name='category'
213-
value={CurrentTool.category}
214-
onChange={handleCategoryChange}
215-
>
216-
<option value="">Select a category</option>
217-
{categories.map(category => (
218-
<option key={category.id} value={category._id}>{category.name}</option>
219-
))}
220-
</select>
221-
</div>
222-
223-
<div className="w-full md:w-full px-3 mb-6 md:mb-0">
224-
<label className="block uppercase tracking-wide text-slate-400 text-xs font-bold mb-2" htmlFor="description">
225-
Tool Description <span className='text-red-500'> *</span>
226-
</label>
227-
<textarea
228-
placeholder='Write up the description'
229-
rows={5}
230-
className="appearance-none block w-full text-slate-300 border border-slate-500 bg-slate-950 rounded py-3 px-4 leading-tight focus:outline-none"
231-
id="description"
232-
name='description'
233-
value={CurrentTool.description}
234-
onChange={handleInputChange}
235-
/>
236-
</div>
237-
238-
<div className="w-full md:w-full px-3 mb-6 md:mb-0">
239-
<label className="block uppercase tracking-wide text-slate-400 text-xs font-bold mb-2" htmlFor="link">
240-
Tool Link <span className='text-red-500'> *</span>
241-
</label>
242-
<input
243-
className="appearance-none block w-full text-slate-300 border border-slate-500 bg-slate-950 rounded py-3 px-4 leading-tight focus:outline-none"
244-
id="link"
245-
name='link'
246-
type="text"
247-
value={CurrentTool.link}
248-
onChange={handleInputChange}
249-
/>
250-
</div>
191+
<title>Submit a new Tool - Which AI</title>
192+
<meta name='title' content='Submit a new Tool - Which AI' />
193+
194+
<div className='px-6 lg:px-16 py-12'>
195+
<div className='lg:flex gap-6 w-full'>
196+
197+
<div className='space-y-6 lg:w-2/3'>
198+
199+
<div className='mx-3'>
200+
<h1 className="text-2xl lg:text-4xl text-slate-200 font-bold ">Submit a new AI Tool</h1>
201+
<p className='border-y-[1px] py-4 my-4 border-slate-600 text-slate-400 text-xs lg:text-sm'> Please provide accurate and complete details when submitting your AI tool. Inaccurate or incomplete information may result in your tool not being published on our website. Your attention to detail helps us maintain a high-quality platform.</p>
202+
</div>
203+
204+
<div className="w-full md:w-full px-3 mb-6 md:mb-0">
205+
<label className="block uppercase tracking-wide text-slate-400 text-xs font-bold mb-2" htmlFor="name">
206+
Tool Name<span className='text-red-500'> *</span>
207+
</label>
208+
<input placeholder='Enter name of tool i.e "Chat GPT"'
209+
className="appearance-none block w-full text-slate-300 border border-slate-500 bg-slate-950 rounded py-3 px-4 leading-tight focus:outline-none "
210+
id="name"
211+
name='name'
212+
type="text"
213+
value={CurrentTool.name}
214+
onChange={handleInputChange}
215+
/>
216+
</div>
217+
218+
<div className="w-full md:w-full px-3 mb-6 md:mb-0">
219+
<label className="block uppercase tracking-wide text-slate-400 text-xs font-bold mb-2" htmlFor="category">
220+
Category<span className='text-red-500'> *</span>
221+
</label>
222+
<select
223+
className="appearance-none block w-full text-slate-300 border border-slate-500 bg-slate-950 rounded py-3 px-4 leading-tight focus:outline-none"
224+
id="category"
225+
name='category'
226+
value={CurrentTool.category}
227+
onChange={handleCategoryChange}
228+
>
229+
<option value="">Select a category</option>
230+
{categories.map(category => (
231+
<option key={category.id} value={category._id}>{category.name}</option>
232+
))}
233+
</select>
234+
</div>
235+
236+
<div className="w-full md:w-full px-3 mb-6 md:mb-0">
237+
<label className="block uppercase tracking-wide text-slate-400 text-xs font-bold mb-2" htmlFor="description">
238+
Tool Description <span className='text-red-500'> *</span>
239+
</label>
240+
<textarea
241+
placeholder='Write up the description'
242+
rows={5}
243+
className="appearance-none block w-full text-slate-300 border border-slate-500 bg-slate-950 rounded py-3 px-4 leading-tight focus:outline-none"
244+
id="description"
245+
name='description'
246+
value={CurrentTool.description}
247+
onChange={handleInputChange}
248+
/>
249+
</div>
251250

252-
<div className="w-full md:w-full px-3 mb-6 md:mb-0">
253-
<label className="block uppercase tracking-wide text-slate-400 text-xs font-bold mb-2" htmlFor="posted_by">
254-
Name <span className='text-red-500'> *</span>
255-
</label>
256-
<input
257-
placeholder='Enter your name for credits'
258-
className="appearance-none block w-full text-slate-300 border border-slate-500 bg-slate-950 rounded py-3 px-4 leading-tight focus:outline-none"
259-
id="posted_by"
260-
type="text"
261-
name='posted_by'
262-
value={CurrentTool.posted_by}
263-
onChange={handleInputChange}
264-
/>
265-
</div>
251+
<div className="w-full md:w-full px-3 mb-6 md:mb-0">
252+
<label className="block uppercase tracking-wide text-slate-400 text-xs font-bold mb-2" htmlFor="link">
253+
Tool Link <span className='text-red-500'> *</span>
254+
</label>
255+
<input
256+
className="appearance-none block w-full text-slate-300 border border-slate-500 bg-slate-950 rounded py-3 px-4 leading-tight focus:outline-none"
257+
id="link"
258+
name='link'
259+
type="text"
260+
value={CurrentTool.link}
261+
onChange={handleInputChange}
262+
/>
263+
</div>
266264

267-
<div className="w-full md:w-full px-3 mb-6 md:mb-0">
268-
<label className="block uppercase tracking-wide text-slate-400 text-xs font-bold mb-2" htmlFor="posted_by_email">
269-
Email <span className='text-red-500'> *</span>
270-
</label>
271-
<input
272-
placeholder='Enter you email (only visible to admin)'
273-
className="appearance-none block w-full text-slate-300 border border-slate-500 bg-slate-950 rounded py-3 px-4 leading-tight focus:outline-none"
274-
id="posted_by_email"
275-
type="email"
276-
name='posted_by_email'
277-
value={CurrentTool.posted_by_email}
278-
onChange={handleInputChange}
279-
/>
280-
</div>
281-
<div className="w-full md:w-full px-3 mb-6 md:mb-0">
282-
<label className="block uppercase tracking-wide text-slate-400 text-xs font-bold mb-2" htmlFor="category">
283-
Tags
284-
</label>
285-
<div className='flex flex-wrap gap-2 appearance-none w-full text-slate-300 border border-slate-500 bg-slate-950 rounded leading-tight '>
286-
<ul className='flex flex-wrap gap-2 py-3 px-4 ' >
287-
{tags.map((tag, index) => (
288-
<li className='text-white bg-slate-500 p-2 flex gap-2 rounded-sm' key={index}>
289-
{tag}
290-
<span className='cursor-pointer hover:text-red-500' onClick={() => removeTag(index)}>×</span>
291-
</li>
292-
))}
265+
<div className="w-full md:w-full px-3 mb-6 md:mb-0">
266+
<label className="block uppercase tracking-wide text-slate-400 text-xs font-bold mb-2" htmlFor="posted_by">
267+
Name <span className='text-red-500'> *</span>
268+
</label>
293269
<input
294-
className='p-2 flex bg-transparent focus:outline-none'
270+
placeholder='Enter your name for credits'
271+
className="appearance-none block w-full text-slate-300 border border-slate-500 bg-slate-950 rounded py-3 px-4 leading-tight focus:outline-none"
272+
id="posted_by"
295273
type="text"
296-
value={newTag}
297-
onChange={handleChangeTags}
298-
onKeyPress={handleKeyPress}
299-
placeholder="Add new tag"
274+
name='posted_by'
275+
value={CurrentTool.posted_by}
276+
onChange={handleInputChange}
300277
/>
301-
</ul>
302-
</div>
303-
</div>
278+
</div>
304279

305-
<ul className=' text-white px-4 text-xs space-y-2'>
306-
{!CurrentTool.name&&<li className='text-slate-500 flex gap-1 items-center'><span className='text-red-500'><MdCancel/></span>Tool name cannot be empty</li>}
307-
{!CurrentTool.description&&<li className='text-slate-500 flex gap-1 items-center'><span className='text-red-500'><MdCancel/></span>Tool Description cannot be empty</li>}
308-
{!CurrentTool.category&&<li className='text-slate-500 flex gap-1 items-center'><span className='text-red-500'><MdCancel/></span>Tool Category cannot be empty</li>}
309-
{!CurrentTool.link&&<li className='text-slate-500 flex gap-1 items-center'><span className='text-red-500'><MdCancel/></span>Tool Link cannot be empty</li>}
280+
<div className="w-full md:w-full px-3 mb-6 md:mb-0">
281+
<label className="block uppercase tracking-wide text-slate-400 text-xs font-bold mb-2" htmlFor="posted_by_email">
282+
Email <span className='text-red-500'> *</span>
283+
</label>
284+
<input
285+
placeholder='Enter you email (only visible to admin)'
286+
className="appearance-none block w-full text-slate-300 border border-slate-500 bg-slate-950 rounded py-3 px-4 leading-tight focus:outline-none"
287+
id="posted_by_email"
288+
type="email"
289+
name='posted_by_email'
290+
value={CurrentTool.posted_by_email}
291+
onChange={handleInputChange}
292+
/>
293+
</div>
294+
<div className="w-full md:w-full px-3 mb-6 md:mb-0">
295+
<label className="block uppercase tracking-wide text-slate-400 text-xs font-bold mb-2" htmlFor="category">
296+
Tags
297+
</label>
298+
<div className='flex flex-wrap gap-2 appearance-none w-full text-slate-300 border border-slate-500 bg-slate-950 rounded leading-tight '>
299+
<ul className='flex flex-wrap gap-2 py-3 px-4 ' >
300+
{tags.map((tag, index) => (
301+
<li className='text-white bg-slate-500 p-2 flex gap-2 rounded-sm' key={index}>
302+
{tag}
303+
<span className='cursor-pointer hover:text-red-500' onClick={() => removeTag(index)}>×</span>
304+
</li>
305+
))}
306+
<input
307+
className='p-2 flex bg-transparent focus:outline-none'
308+
type="text"
309+
value={newTag}
310+
onChange={handleChangeTags}
311+
onKeyPress={handleKeyPress}
312+
placeholder="Add new tag"
313+
/>
314+
</ul>
315+
</div>
316+
</div>
317+
318+
<ul className=' text-white px-4 text-xs space-y-2'>
319+
{!CurrentTool.name && <li className='text-slate-500 flex gap-1 items-center'><span className='text-red-500'><MdCancel /></span>Tool name cannot be empty</li>}
320+
{!CurrentTool.description && <li className='text-slate-500 flex gap-1 items-center'><span className='text-red-500'><MdCancel /></span>Tool Description cannot be empty</li>}
321+
{!CurrentTool.category && <li className='text-slate-500 flex gap-1 items-center'><span className='text-red-500'><MdCancel /></span>Tool Category cannot be empty</li>}
322+
{!CurrentTool.link && <li className='text-slate-500 flex gap-1 items-center'><span className='text-red-500'><MdCancel /></span>Tool Link cannot be empty</li>}
323+
324+
{!CurrentTool.posted_by && <li className='text-slate-500 flex gap-1 items-center'><span className='text-red-500'><MdCancel /></span>Name for credits cannot be empty</li>}
325+
{!CurrentTool.posted_by_email && <li className='text-slate-500 flex gap-1 items-center'><span className='text-red-500'><MdCancel /></span>Email is required</li>}
326+
327+
328+
{CurrentTool.posted_by_email && CurrentTool.posted_by && CurrentTool.link && CurrentTool.description && CurrentTool.link && CurrentTool.category && CurrentTool.posted_by && CurrentTool.posted_by_email && <li className='flex gap-1 items-center'><span className='text-green-500'><MdCheckCircle /></span>You are good to submit (Admin will verfiy the details and publish your tool as soon as possible)</li>}
329+
</ul>
310330

311-
{!CurrentTool.posted_by&&<li className='text-slate-500 flex gap-1 items-center'><span className='text-red-500'><MdCancel/></span>Name for credits cannot be empty</li>}
312-
{!CurrentTool.posted_by_email&&<li className='text-slate-500 flex gap-1 items-center'><span className='text-red-500'><MdCancel/></span>Email is required</li>}
331+
<div className='w-full md:w-full px-3 mb-6 md:mb-0'>
332+
<button disabled={(CurrentTool.link && CurrentTool.description && CurrentTool.link && CurrentTool.category) ? false : true} onClick={handleSubmit}
333+
className="bg-slate-200 hover:bg-slate-300 font-bold text-slate-900 w-full py-2 px-4 rounded">
334+
Submit a new Tool
335+
</button></div>
313336

314-
315-
{CurrentTool.posted_by_email&&CurrentTool.posted_by&&CurrentTool.link&&CurrentTool.description&&CurrentTool.link&&CurrentTool.category&&CurrentTool.posted_by&&CurrentTool.posted_by_email&&<li className='flex gap-1 items-center'><span className='text-green-500'><MdCheckCircle/></span>You are good to submit (Admin will verfiy the details and publish your tool as soon as possible)</li>}
316-
</ul>
317337

318-
<div className='w-full md:w-full px-3 mb-6 md:mb-0'>
319-
<button disabled ={(CurrentTool.link&&CurrentTool.description&&CurrentTool.link&&CurrentTool.category)?false:true} onClick={handleSubmit}
320-
className="bg-slate-200 hover:bg-slate-300 font-bold text-slate-900 w-full py-2 px-4 rounded">
321-
Submit a new Tool
322-
</button></div>
323338

339+
</div>
324340

341+
<div className='hidden lg:w-1/3 lg:flex justify-center sticky top-48 h-full'>
342+
<ToolCard tool={CurrentTool} />
343+
</div>
325344

326-
</div>
327345

328-
<div className='hidden lg:w-1/3 lg:flex justify-center sticky top-48 h-full'>
329-
<ToolCard tool={CurrentTool} />
346+
</div>
330347
</div>
331-
332-
333-
</div>
334-
</div>
335-
</>
348+
</>
336349
)
337350
}
338351

0 commit comments

Comments
 (0)