Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/apis/restful/controllers/ArticleController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default class ArticleController {
'text',
'views',
'updatedAt',
'createdAt',
],
['firstname', 'lastname', 'profile_image'],
),
Expand Down
4 changes: 2 additions & 2 deletions src/modules/activities/ContactActivity/social_medias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Call, Email, Facebook,Twitter, WhatsApp, LinkedIn } from '@mui/icons-ma
const social_medias = [
{
name:"Facebook",
link:"https://web.facebook.com/YEANAGRO",
link:"https://www.facebook.com/share/g/1C3oFs5joM/?mibextid=wwXIfr",
bg_color:"bg-[#4267B2]",
logo:Facebook,
},
Expand All @@ -15,7 +15,7 @@ const social_medias = [

{
name:"WhatsApp",
link:"https://api.whatsapp.com/send?phone=250788940434",
link:"https://api.whatsapp.com/send?phone=250792397594",
bg_color:"bg-[#00a884]",
logo:WhatsApp,
},
Expand Down
4 changes: 2 additions & 2 deletions src/modules/activities/FarmerPlatformActivity/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ const FarmerPlatformActivity = () => {

<div className="flex items-center flex-wrap gap-4 justify-center w-full bg-[#F7F6F6] p-4 md:p-8 mx-auto">
<a
href="https://www.facebook.com/groups/farmerplatform/?ref=share_group_link"
href="https://www.facebook.com/share/g/1C3oFs5joM/?mibextid=wwXIfr"
target="_blank"
rel="noopener noreferrer"
className="bg-[#4267B2] text-lg text-white rounded-lg py-3 px-4"
Expand All @@ -129,7 +129,7 @@ const FarmerPlatformActivity = () => {
</a>

<a
href="https://wa.me/+250788845727"
href="https://wa.me/250792397594"
target="_blank"
rel="noopener noreferrer"
className="bg-[#3B951C] text-lg text-white rounded-lg py-3 px-4"
Expand Down
25 changes: 14 additions & 11 deletions src/modules/activities/LandingActivity/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ import { useRouter } from 'next/router';
import { slideUpItems } from './data';
import SlideUpItem from './SlideUpItem';
import { Banner } from 'types/types';
import CustomImage from 'modules/_partials/CustomImage';

const LandingAcitivity = ({
banners,
recentArticles,
recentExtensionMaterials,
slides,
}: {
banners?: Banner[];
banners: Record<string, Banner>;
recentArticles: any[];
recentExtensionMaterials: any[];
slides: any[];
Expand All @@ -37,18 +38,20 @@ const LandingAcitivity = ({
const confirmedPartners = partners?.rows;

const renderBanners = (section: string) => {
const banner = banners?.find(
banner => banner.section === section,
);
const banner = banners[section];

if (!banner) return null;

return (
<div key={banner.id} className="px-4 md:px-8 py-2 bg-white">
<div
id={section}
key={banner.id}
className="px-4 md:px-8 py-2 bg-white"
>
<div className="flex flex-col relative min-h-[64px] md:min-h-[195px]">
<Link href={banner.url || '#'}>
<Image
src={banner.image}
<Link href={banner.path || '#'}>
<CustomImage
src={banner.url}
alt={banner.title}
layout="fill"
loading="lazy"
Expand Down Expand Up @@ -110,7 +113,7 @@ const LandingAcitivity = ({
/>
))}
</div>
{renderBanners('products')} {/* it must be section products */}
{renderBanners('first')} {/* it must be section products */}
<div className="flex flex-col px-4 md:px-8 py-2 bg-white">
<h1 className="text-2xl md:text-4xl text-white font-bold bg-brand-green p-2 text-center">
Extension Materials
Expand All @@ -133,7 +136,7 @@ const LandingAcitivity = ({
<span>View More</span>
</button>
</div>
{renderBanners('services')} {/* it must be section services */}
{renderBanners('second')} {/* it must be section services */}
<div className="flex flex-col px-4 md:px-8 py-2 bg-white">
<h1 className="text-2xl md:text-4xl text-white font-bold bg-brand-green p-2 text-center">
Latest Blog
Expand All @@ -156,7 +159,7 @@ const LandingAcitivity = ({
<span>View More</span>
</button>
</div>
{renderBanners('about')} {/* it must be section about */}
{renderBanners('third')} {/* it must be section about */}
<div className="flex flex-col px-4 md:px-8 py-2 bg-white">
<h1 className="text-2xl md:text-4xl text-white font-bold bg-brand-green p-2 text-center">
Our Partners
Expand Down
2 changes: 1 addition & 1 deletion src/modules/admin/BannerActivity/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const BannerActivity: React.FC = () => {
// Filter banners based on search input
const filteredBanners = React.useMemo(() => {
return banners.filter(banner =>
banner.title.toLowerCase().includes(filterValue.toLowerCase()),
banner.title?.toLowerCase().includes(filterValue.toLowerCase()),
);
}, [banners, filterValue]);

Expand Down
118 changes: 62 additions & 56 deletions src/modules/admin/_Partials/ManageBanners/AddBanner/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @next/next/no-img-element */
import React, { useState } from 'react';
import {
Dialog,
Expand All @@ -11,38 +12,43 @@ import {
MenuItem,
FormControl,
InputLabel,
Alert
Alert,
} from '@mui/material';
import { CloudUpload, Close } from '@mui/icons-material';
import { useDropzone } from 'react-dropzone';
import { Banner } from 'types/types';
import { useRouter } from 'next/router';

interface AddBannerProps {
onAdd: (banner: Banner) => void;
children: React.ReactNode;
allowedTypes?: string[];
}

interface FormData {
title: string;
url: string;
section: string;
path: string;
image: File | null;
}

const INITIAL_FORM_STATE: FormData = {
title: '',
url: '',
section: '',
path: '',
image: null,
};

const sections = ['products', 'services', 'about'];
const sections = [1, 2, 3];

export default function AddBanner({ onAdd, children }: AddBannerProps) {
export default function AddBanner({
onAdd,
children,
allowedTypes = ['image/png', 'image/jpeg', 'image/gif'],
}: AddBannerProps) {
const router = useRouter();
const [open, setOpen] = useState(false);
const [formData, setFormData] = useState<FormData>(INITIAL_FORM_STATE);
const [formData, setFormData] = useState<FormData>(
INITIAL_FORM_STATE,
);
const [isSubmitting, setIsSubmitting] = useState(false);
const [previewUrl, setPreviewUrl] = useState<string>('');
const [error, setError] = useState<string>('');
Expand Down Expand Up @@ -71,14 +77,13 @@ export default function AddBanner({ onAdd, children }: AddBannerProps) {
return;
}

setFormData((prev) => ({ ...prev, image: file }));
setFormData(prev => ({ ...prev, image: file }));
setPreviewUrl(URL.createObjectURL(file));
setError('');
};

const { getRootProps, getInputProps } = useDropzone({
onDrop,
accept: 'image/*' as any,
maxSize: 100 * 1024 * 1024, //100MB
});

Expand All @@ -88,9 +93,11 @@ export default function AddBanner({ onAdd, children }: AddBannerProps) {
setError('');

try {
const { title, url, section, path, image } = formData;
if (!title.trim() || !url.trim() || !section.trim() || !path.trim() || !image) {
throw new Error('Please fill in all required fields completely');
const { section, path, image } = formData;
if (!section || !image || !path.trim()) {
throw new Error(
'Please fill in all required fields completely',
);
}

const submitFormData = new FormData();
Expand All @@ -107,14 +114,19 @@ export default function AddBanner({ onAdd, children }: AddBannerProps) {

if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.message || 'Failed to create banner');
throw new Error(
errorData.message || 'Failed to create banner',
);
}

const newBanner = await response.json();
onAdd(newBanner);
// onAdd(newBanner);
handleClose();
router.reload();
} catch (err) {
setError(err instanceof Error ? err.message : 'An error occurred');
setError(
err instanceof Error ? err.message : 'An error occurred',
);
} finally {
setIsSubmitting(false);
}
Expand Down Expand Up @@ -143,64 +155,51 @@ export default function AddBanner({ onAdd, children }: AddBannerProps) {

<form onSubmit={handleSubmit}>
<DialogContent>
<TextField
fullWidth
label="Title"
value={formData.title}
onChange={(e) => setFormData((prev) => ({ ...prev, title: e.target.value }))}
required
disabled={isSubmitting}
margin="normal"
variant="outlined"
color="success"
/>

<TextField
fullWidth
label="URL"
type="url"
value={formData.url}
onChange={(e) => setFormData((prev) => ({ ...prev, url: e.target.value }))}
required
disabled={isSubmitting}
margin="normal"
variant="outlined"
color="success"
/>

<FormControl fullWidth margin="normal" required>
<InputLabel>Section</InputLabel>
<Select
value={formData.section}
label="Section"
onChange={(e) => setFormData((prev) => ({ ...prev, section: e.target.value }))}
onChange={e =>
setFormData(prev => ({
...prev,
section: e.target.value,
}))
}
disabled={isSubmitting}
color="success"
>
{sections.map((section) => (
{sections.map(section => (
<MenuItem key={section} value={section}>
{section.charAt(0).toUpperCase() + section.slice(1)}
{`Banner ${section}`}
</MenuItem>
))}
</Select>
</FormControl>

<TextField
fullWidth
label="Path"
label="Link To Page"
value={formData.path}
onChange={(e) => setFormData((prev) => ({ ...prev, path: e.target.value }))}
onChange={e =>
setFormData(prev => ({
...prev,
path: e.target.value,
}))
}
required
disabled={isSubmitting}
margin="normal"
variant="outlined"
color="success"
type="url"
/>

<input
{...getInputProps()}
style={{ display: 'none' }}
id="banner-file-upload"
accept={allowedTypes.join(',')}
/>

<label
Expand All @@ -209,10 +208,15 @@ export default function AddBanner({ onAdd, children }: AddBannerProps) {
cursor-pointer flex flex-col items-center justify-center
w-full h-48 border-2 border-dashed rounded-lg
mt-4 transition-colors duration-200
${isSubmitting ? 'bg-green-50' :
error ? 'border-red-300 bg-red-50' :
previewUrl ? 'border-green-500 bg-green-50' :
'border-green-300 hover:border-green-500'}
${
isSubmitting
? 'bg-green-50'
: error
? 'border-red-300 bg-red-50'
: previewUrl
? 'border-green-500 bg-green-50'
: 'border-green-300 hover:border-green-500'
}
`}
{...getRootProps()}
>
Expand All @@ -221,13 +225,13 @@ export default function AddBanner({ onAdd, children }: AddBannerProps) {
<img
src={previewUrl}
alt="Preview"
className="max-h-35 w-auto object-contain"
className="max-h-35 w-auto object-contain mt-48"
/>
<IconButton
size="small"
onClick={(e) => {
onClick={e => {
e.stopPropagation();
setFormData((prev) => ({ ...prev, image: null }));
setFormData(prev => ({ ...prev, image: null }));
setPreviewUrl('');
}}
sx={{
Expand All @@ -236,15 +240,17 @@ export default function AddBanner({ onAdd, children }: AddBannerProps) {
right: -10,
backgroundColor: 'green',
color: 'white',
'&:hover': { backgroundColor: 'darkgreen' }
'&:hover': { backgroundColor: 'darkgreen' },
}}
>
<Close fontSize="small" />
</IconButton>
</div>
) : (
<div className="flex flex-col items-center justify-center h-full">
<CloudUpload sx={{ fontSize: 64, color: 'green', mb: 2 }} />
<CloudUpload
sx={{ fontSize: 64, color: 'green', mb: 2 }}
/>
<span className="text-lg text-center text-green-600">
Drag and Drop Banner Image
</span>
Expand Down Expand Up @@ -276,7 +282,7 @@ export default function AddBanner({ onAdd, children }: AddBannerProps) {
</Button>
<Button
type="submit"
variant="contained"
variant="outlined"
disabled={isSubmitting || !formData.image}
color="success"
>
Expand Down
Loading