Skip to content

Instantly share code, notes, and snippets.

@adrianhajdin
Last active April 22, 2024 15:29
Show Gist options
  • Save adrianhajdin/c9e83f0fb1dfcf238dae0cc68a90ba82 to your computer and use it in GitHub Desktop.
Save adrianhajdin/c9e83f0fb1dfcf238dae0cc68a90ba82 to your computer and use it in GitHub Desktop.
Build and Deploy a Full Stack MERN Dashboard App With CRUD, Auth, and Charts Using Refine
import { ApexOptions } from 'apexcharts';
export const TotalRevenueSeries = [
{
name: 'Last Month',
data: [183, 124, 115, 85, 143, 143, 96],
},
{
name: 'Running Month',
data: [95, 84, 72, 44, 108, 108, 47],
},
];
export const TotalRevenueOptions: ApexOptions = {
chart: {
type: 'bar',
toolbar: {
show: false,
},
},
colors: ['#475BE8', '#CFC8FF'],
plotOptions: {
bar: {
borderRadius: 4,
horizontal: false,
columnWidth: '55%',
},
},
dataLabels: {
enabled: false,
},
grid: {
show: false,
},
stroke: {
colors: ['transparent'],
width: 4,
},
xaxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'],
},
yaxis: {
title: {
text: '$ (thousands)',
},
},
fill: {
opacity: 1,
},
legend: {
position: 'top',
horizontalAlign: 'right',
},
tooltip: {
y: {
formatter(val: number) {
return `$ ${val} thousands`;
},
},
},
};
import { Email, Phone, Place } from '@mui/icons-material';
import { Box, Stack, Typography } from '@pankod/refine-mui';
import { ProfileProps, PropertyProps } from 'interfaces/common';
import PropertyCard from './PropertyCard';
function checkImage(url: any) {
let img = new Image();
img.src = url;
return img.width !== 0 && img.height !== 0;
}
const Profile = ({ type, name, avatar, email, properties }: ProfileProps) => (
<Box>
<Typography fontSize={25} fontWeight={700} color="#11142D">{type} Profile</Typography>
<Box
mt="20px"
borderRadius="15px"
padding="20px"
bgcolor="#FCFCFC"
>
<Box
sx={{
display: 'flex',
flexDirection: { xs: 'column', md: 'row' },
gap: 2.5,
}}
>
<img
src="https://images.unsplash.com/photo-1618005198919-d3d4b5a92ead?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1374&q=80"
width={340}
height={320}
alt="abstract"
className="my_profile-bg"
/>
<Box
flex={1}
sx={{ marginTop: { md: '58px' }, marginLeft: { xs: '20px', md: '0px' } }}
>
<Box flex={1} display="flex" flexDirection={{ xs: 'column', md: 'row' }} gap="20px">
<img
src={checkImage(avatar) ? avatar : "https://upload.wikimedia.org/wikipedia/commons/thumb/5/59/User-avatar.svg/2048px-User-avatar.svg.png"}
width={78}
height={78}
alt="user_profile"
className="my_profile_user-img"
/>
<Box flex={1} display="flex" flexDirection="column" justifyContent="space-between" gap="30px">
<Stack direction="column">
<Typography fontSize={22} fontWeight={600} color="#11142D">{name}</Typography>
<Typography fontSize={16} color="#808191">Realestate Agent</Typography>
</Stack>
<Stack direction="column" gap="30px">
<Stack gap="15px">
<Typography fontSize={14} fontWeight={500} color="#808191">Address</Typography>
<Box display="flex" flexDirection="row" alignItems="center" gap="10px">
<Place sx={{ color: '#11142D' }} />
<Typography fontSize={14} color="#11142D">4517 Washington Ave. Manchaster, Kentucky 39495</Typography>
</Box>
</Stack>
<Stack direction="row" flexWrap="wrap" gap="20px" pb={4}>
<Stack flex={1} gap="15px">
<Typography fontSize={14} fontWeight={500} color="#808191">Phone Number</Typography>
<Box display="flex" flexDirection="row" alignItems="center" gap="10px">
<Phone sx={{ color: '#11142D' }} />
<Typography fontSize={14} color="#11142D" noWrap>+0123 456 7890</Typography>
</Box>
</Stack>
<Stack flex={1} gap="15px">
<Typography fontSize={14} fontWeight={500} color="#808191">Email</Typography>
<Box display="flex" flexDirection="row" alignItems="center" gap="10px">
<Email sx={{ color: '#11142D' }} />
<Typography fontSize={14} color="#11142D">{email}</Typography>
</Box>
</Stack>
</Stack>
</Stack>
</Box>
</Box>
</Box>
</Box>
</Box>
{properties.length > 0 && (
<Box
mt={2.5}
borderRadius="15px"
padding="20px"
bgcolor="#FCFCFC"
>
<Typography fontSize={18} fontWeight={600} color="#11142D">{type} Properties</Typography>
<Box
mt={2.5}
sx={{
display: 'flex',
flexWrap: 'wrap',
gap: 2.5,
}}
>
{properties?.map((property: PropertyProps) => (
<PropertyCard key={property._id} id={property._id}
title={property.title}
location={property.location}
price={property.price}
photo={property.photo}
/>
))}
</Box>
</Box>
)}
</Box>
);
export default Profile;
// common
import Profile from './common/Profile';
import PropertyCard from './common/PropertyCard';
import CustomButton from './common/CustomButton';
// charts
import PieChart from './charts/PieChart';
import PropertyReferrals from './charts/PropertyReferrals';
import TotalRevenue from './charts/TotalRevenue';
// agent
import AgentCard from './agent/AgentCard';
// home
import TopAgent from './home/TopAgent';
export {
Profile,
PropertyCard,
CustomButton,
PieChart,
PropertyReferrals,
TotalRevenue,
AgentCard,
TopAgent,
};
export const propertyReferralsInfo = [
{
title: 'Social Media',
percentage: 64,
color: '#6C5DD3',
},
{
title: 'Marketplace',
percentage: 40,
color: '#7FBA7A',
},
{
title: 'Websites',
percentage: 50,
color: '#FFCE73',
},
{
title: 'Digital Ads',
percentage: 80,
color: '#FFA2C0',
},
{
title: 'Others',
percentage: 15,
color: '#F45252',
},
];
* {
font-family: 'Manrope', sans-serif !important;
}
a {
text-decoration: none !important;
}
.my_profile-bg {
width: 340px;
border-top-left-radius: 15px;
border-bottom-left-radius: 15px;
}
.my_profile_user-img {
border-radius: 100%;
margin-left: -64px;
}
.property_details-img {
width: 100%;
}
@media screen and (max-width: 900px) {
.my_profile-bg {
width: 100%;
border-radius: 15px;
}
.my_profile_user-img {
margin-left: 0px;
margin-top: -64px;
}
.property_details-img {
width: 100%;
height: auto;
}
}
import { useState } from 'react';
import { useGetIdentity } from '@pankod/refine-core';
import { FieldValues, useForm } from '@pankod/refine-react-hook-form';
import Form from 'components/common/Form';
const CreateProperty = () => {
const { data: user } = useGetIdentity();
const [propertyImage, setPropertyImage] = useState({ name: '', url: '' });
const { refineCore: { onFinish, formLoading }, register, handleSubmit } = useForm();
const handleImageChange = (file: File) => {
const reader = (readFile: File) => new Promise<string>((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = () => resolve(fileReader.result as string);
fileReader.readAsDataURL(readFile);
});
reader(file).then((result: string) => setPropertyImage({ name: file?.name, url: result }));
};
const onFinishHandler = async (data: FieldValues) => {
if(!propertyImage.name) return alert('Please select an image');
await onFinish({ ...data, photo: propertyImage.url, email: user.email })
};
return (
<Form
type="Create"
register={register}
onFinish={onFinish}
formLoading={formLoading}
handleSubmit={handleSubmit}
handleImageChange={handleImageChange}
onFinishHandler={onFinishHandler}
propertyImage={propertyImage}
/>
)
}
export default CreateProperty
import { useState } from 'react';
import { useGetIdentity } from '@pankod/refine-core';
import { FieldValues, useForm } from '@pankod/refine-react-hook-form';
import Form from 'components/common/Form';
const CreateProperty = () => {
const { data: user } = useGetIdentity();
const [propertyImage, setPropertyImage] = useState({ name: '', url: '' });
const { refineCore: { onFinish, formLoading }, register, handleSubmit } = useForm();
const handleImageChange = (file: File) => {
const reader = (readFile: File) => new Promise<string>((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = () => resolve(fileReader.result as string);
fileReader.readAsDataURL(readFile);
});
reader(file).then((result: string) => setPropertyImage({ name: file?.name, url: result }));
};
const onFinishHandler = async (data: FieldValues) => {
if (!propertyImage.name) return alert('Please upload a property image');
await onFinish({ ...data, photo: propertyImage.url, email: user.email });
};
return (
<Form
type="Edit"
register={register}
onFinish={onFinish}
formLoading={formLoading}
handleSubmit={handleSubmit}
handleImageChange={handleImageChange}
onFinishHandler={onFinishHandler}
propertyImage={propertyImage}
/>
);
};
export default CreateProperty;
import AgentProfile from './agent-profile';
import Agents from './agent';
import AllProperties from './all-properties';
import CreateProperty from './create-property';
import Home from './home';
import { Login } from './login';
import MyProfile from './my-profile';
import PropertyDetails from './property-details';
import EditProperty from './edit-property';
export {
AgentProfile,
Agents,
AllProperties,
CreateProperty,
Home,
Login,
MyProfile,
PropertyDetails,
EditProperty,
};
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@200;300;400;500;600;700;800&display=swap" rel="stylesheet">
/* eslint-disable no-plusplus */
import { FormValues } from 'interfaces/property';
export const validateForm = (formValues: FormValues) => {
const errors: { message: string } = { message: '' };
let hasError = false;
Object.keys(formValues).forEach((key) => {
switch (key) {
case 'title':
if (!formValues.title) {
errors.message = 'Title is required';
hasError = true;
}
break;
case 'description':
if (!formValues.description) {
errors.message = 'Description is required';
hasError = true;
}
break;
case 'propertyType':
if (!formValues.propertyType) {
errors.message = 'Property type is required';
hasError = true;
}
break;
case 'location':
if (!formValues.location) {
errors.message = 'Location is required';
hasError = true;
}
break;
case 'price':
if (!formValues.price) {
errors.message = 'Price is required';
hasError = true;
}
break;
default:
hasError = false;
}
});
return { hasError, errors };
};
export const hasChanged = (initialValues: FormValues, currentValues: FormValues) => {
const initialValuesArray = Object.values(initialValues);
const currentValuesArray = Object.values(currentValues);
for (let i = 0; i < initialValuesArray.length; i++) {
if (initialValuesArray[i] !== currentValuesArray[i]) {
return true;
}
}
return false;
};
@TrxMod21X
Copy link

i get this message after chosing google account to login

_ref3 is undefined
TypeError

i have no idea what that's mean, can someone give me solution?

@array-web
Copy link

Screenshot 2023-03-17 at 11 29 43 PM

I'm facing this error someone please look into it

@himanshu1161
Copy link

delete button showing 404 error any solutin ?

@himanshu1161
Copy link

when i trying to delete a propert it is showing 404 error any solution ?
i tried everything

@BDedafoe
Copy link

Good Afternoon house. I have a challenge on my create property page , the form , When I fill it, it doesn't display except I highlight. I guess its the color of the text I have tried to change the color but I have not been able. Can anyone assist, or anyone with this issue that has solved same assist. form

Not sure if you have figured this one out yet but just in case you're still stuck, there is an issue with going between dark and light mode. Just go to the App.tsx file in the client folder and remove the ColorModeContextProvider component at the bottom and remove the import at the top as well. This worked for me

@wivalconcept
Copy link

wivalconcept commented Mar 27, 2023 via email

@wivalconcept
Copy link

Good Afternoon house. I have a challenge on my create property page , the form , When I fill it, it doesn't display except I highlight. I guess its the color of the text I have tried to change the color but I have not been able. Can anyone assist, or anyone with this issue that has solved same assist. form

Not sure if you have figured this one out yet but just in case you're still stuck, there is an issue with going between dark and light mode. Just go to the App.tsx file in the client folder and remove the ColorModeContextProvider component at the bottom and remove the import at the top as well. This worked for me

@BDedafoe shared this with me and it worked for me you can do same

Not sure if you have figured this one out yet but just in case you're still stuck, there is an issue with going between dark and light mode. Just go to the App.tsx file in the client folder and remove the ColorModeContextProvider component at the bottom and remove the import at the top as well. This worked for me

@wivalconcept
Copy link

Login error
I have a challenge, my site was working well until I created the Property and User page. When I tried to reload my site, I can no longer login with my Google ID give the above error.

@sujoyduttajad
Copy link

Looks like you used the deleteOne() method from MongoDB but does it also deletes the property from the creator

@ronicTakouugang
Copy link

Did you remove the message on top? 🧙‍♂️Refine grants your wishes! Please give us a ⭐️ on GitHub to keep the magic going. It sucks!

@ronicTakouugang
Copy link

i get this message after chosing google account to login

_ref3 is undefined TypeError

i have no idea what that's mean, can someone give me solution?

Got the same error bro

@JPS-747
Copy link

JPS-747 commented Apr 28, 2023

Hi,
You can't assign the Promise into a string field.

ERROR in src/App.tsx:59:5
TS2322: Type '({ credential }: CredentialResponse) => Promise<void | AuthActionResponse>' is not assignable to type '(params: any) => Promise'.

@webdSUNIL
Copy link

can someone plese send me the full code ?

@smolkawaii1
Copy link

Did you remove the message on top? 🧙‍♂️Refine grants your wishes! Please give us a ⭐️ on GitHub to keep the magic going. It sucks!

Hello guys, I'm new to this refine dev and MERN stack web dev, I just wondering if is there any solution in removing the "🧙‍♂️
refine grants your wishes! Please give us a ⭐️ on GitHub to keep the magic going." banner?

@ReddyMahithaBusetty
Copy link

Did you remove the message on top? 🧙‍♂️Refine grants your wishes! Please give us a ⭐️ on GitHub to keep the magic going. It sucks!

Hello guys, I'm new to this refine dev and MERN stack web dev, I just wondering if is there any solution in removing the "🧙‍♂️ refine grants your wishes! Please give us a ⭐️ on GitHub to keep the magic going." banner?

Hiya, you just have to remove GitHubBanner, and lines of code from your App.tsx to remove "🧙‍♂️
refine grants your wishes! Please give us a ⭐️ on GitHub to keep the magic going....Thank you.

@smolkawaii1
Copy link

smolkawaii1 commented May 7, 2023 via email

@ZulfanoRp
Copy link

when I install refine, the component only has a header, no siders, what's the solution

@xexino
Copy link

xexino commented May 22, 2023

when I install refine, the component only has a header, no siders, what's the solution 2 !! :)

@YoussefEmad6
Copy link

when I install refine, the component only has a header, no siders, what's the solution

@fazzy12
Copy link

fazzy12 commented Jun 6, 2023

when I install refine, the component only has a header, no siders, what's the solution
having the same issue, what is the solution?

@Robj1925
Copy link

Robj1925 commented Jun 7, 2023

when I install refine, the component only has a header, no siders, what's the solution

@sujoyduttajad
Copy link

Does anyone was successful in implementing the DarkMode toggle

Please let me know how you did it, I tried but just couldn't implement it

@khatiazitanishvili
Copy link

when I install refine, the component only has a header, no siders, what's the solution

@rounitverma
Copy link

it won't throw an error as siders and other parameters are not being imported. Just move ahead

@zmanhcong
Copy link

when I install refine, the component only has a header, no siders, what's the solution

same issue, it seem refine was update neweast version so we have to refactor the code.

@Yosef-Ali
Copy link

when I install refine, the component only has a header, no siders, what's the solution

same issue, it seem refine was update neweast version so we have to refactor the code.

Run the swizzle command in the project directory i fund in the doc npm run refine swizzle

@shithinshetty
Copy link

Screenshot 2023-03-11 at 1 58 10 PM

i'm facing an error in login with google. A popup window opens with no content can someone help me out?

While Creating OAuth CRED change the https://localhost:3000 to http://localhost:3000

@saibadarinadh
Copy link

image

@dipak-wagh
Copy link

in above validateForm file,i used in my project.but it gives error ->interface/property cannot find.

@ArfaniAsra
Copy link

when I install refine, the component only has a header, no siders, what's the solution
same issue, it seem refine was update neweast version so we have to refactor the code.

Run the swizzle command in the project directory i fund in the doc npm run refine swizzle

when I install refine, the component only has a header, no siders, what's the solution
same issue, it seem refine was update neweast version so we have to refactor the code.

Run the swizzle command in the project directory i fund in the doc npm run refine swizzle

Hi, I want to ask. after running this command, what should we choose between 3 of these following items:
Data Provider
@refinedev/simple-rest
UI Framework
@refinedev/core
@refinedev/mui

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment