Skip to content

Commit

Permalink
feat: Project edition
Browse files Browse the repository at this point in the history
  • Loading branch information
maricdiranovic committed Feb 11, 2025
1 parent 495af86 commit efe1284
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 13 deletions.
2 changes: 1 addition & 1 deletion client/src/containers/cards/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const Cards = ({ data = [], theme = 'grey', pathname, project = false }: CardsPr
</div>
)}
{data.map((item) => (
<Card theme={theme} key={item.id} href={`${pathname}/${item.id}`} {...item} />
<Card theme={theme} key={item.id} href={`${pathname}/${item.id}${project ? '/edit' : ''}`} {...item} />
))}
</div>
);
Expand Down
33 changes: 22 additions & 11 deletions client/src/containers/my-projects/sidebar/projectDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ import CHEVRON_RIGHT from 'svgs/icons/arrow-right.svg?sprite';
import LOCK from 'svgs/icons/lock.svg?sprite';
import USER_TWO from 'svgs/icons/user-two.svg?sprite';
import { useDispatch } from 'react-redux';
import { Field } from 'react-final-form';
import { Placement } from '@floating-ui/react-dom-interactions';
import { useAppSelector } from 'store/hooks';
import { RootState } from 'store';
const ProjectDetails = () => {
const [logo, setLogo] = useState<File | null>(null);
const draft = useAppSelector((state: RootState) => state['/projectForm'])

const dispatch = useDispatch();

Expand Down Expand Up @@ -48,17 +53,20 @@ const ProjectDetails = () => {
<label className='flex'>
<Icon icon={eye} className="w-4 h-4 pr-1" />PARTNER ORGANIZATION NAME <span className="text-red-0">*</span>
</label>
<input
type="text"
className="w-full p-2 mt-2 border border-gray-300 rounded-lg outline-none focus:ring focus:ring-blue-200"

<Field name="name"
value={draft.draftProject.name}
component={"input"}
className="w-full p-2 mt-2 border border-gray-300 rounded-lg outline-none focus:ring focus:ring-blue-200"
/>
</div>

<div className="flex flex-col py-2">
<label className='flex'><Icon icon={eye} className="w-4 h-4 pr-1" />PROJECT WEBSITE</label>
<input
type="text"
className="w-full p-2 mt-2 border border-gray-800 rounded-lg outline-none focus:ring focus:ring-blue-200"

<Field name="website"
component="input"
className="w-full p-2 mt-2 border border-gray-300 rounded-lg outline-none focus:ring focus:ring-blue-200"
/>
</div>
</div>
Expand All @@ -67,12 +75,15 @@ const ProjectDetails = () => {
<label className="flex pb-3 font-medium text-gray-700 "><Icon icon={eye} className="w-4 h-4 pr-1" />
Description <span className="text-red-0">*</span>
</label>
<textarea
className="w-full h-32 p-3 my-3 border border-gray-300 rounded-lg outline-none focus:ring focus:ring-blue-200"
></textarea>

<Field
name="description"
component="textarea"
className="w-full h-32 p-3 my-3 border border-gray-300 rounded-lg outline-none focus:none "
/>
</div>

{/* Upload Logo */}

<div className="mt-6">
<label className="flex mb-1 font-medium text-gray-700">
<Icon icon={eye} className="w-4 h-4 pr-1" /> LOGO
Expand All @@ -92,7 +103,7 @@ const ProjectDetails = () => {
)}
</div>
</div>

<div className="mt-6">
<label className="flex mb-1 font-medium text-gray-700">
<Icon icon={eye} className="w-4 h-4 pr-1" />
Expand Down
21 changes: 21 additions & 0 deletions client/src/hooks/my-projects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ export const fetchMemberProjects = (params: MyProjectProps) => {
}).then(res => res.data);
}

export const fetchMyProject = (id: string) => {
return API.request({
method: 'GET',
url: `/my-projects/${id}`,

}).then((res) => res.data);
}

export function useFetchMemberProjects(params: MyProjectProps = {}, queryOption: UseQueryOptions<Project[], unknown> = {}) {
const fetch = () =>
fetchMemberProjects({
Expand Down Expand Up @@ -72,3 +80,16 @@ export function useMyInfinityProjects(
data: DATA,
};
}


export function useMyProject(id: string, queryOptions: UseQueryOptions<Project, unknown> = {}){
const fetch = () => fetchMyProject(id);

const query = useQuery(['myProject', id], fetch, {
enabled: !!id,
placeholderData: {data: {}},
...queryOptions,
})

return query;
}
40 changes: 40 additions & 0 deletions client/src/pages/my-projects/[projectId]/edit/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { useMyProject } from 'hooks/my-projects';
import { NextPage } from 'next'
import { useRouter } from 'next/router'
import React from 'react'
import MetaTags from 'containers/meta-tags';
import ProtectedRoute from 'hoc/protectedRoute';
import NewProjectLayout from 'pages/my-projects/new/layout';
import ProjectForm from 'containers/my-projects/sidebar/form';

// export const getServerSideProps = getReduxStateFromQuery();

const TITLE_TEXT = 'FORA Projects | FORA supported regenerative agriculture projects';
const DESCRIPTION_TEXT =
'Stay up-to-date on the what, who, and where of the funding and strategies of FORA members for synergistic collaboration in support of your work.';
const IMAGE_URL = `${process.env.NEXT_PUBLIC_BASE_PATH}images/meta/projects.jpg`;


const EditProject: NextPage = () => {
const {query} = useRouter();
const {id: projectId} = query;
const {data: myProjectData} = useMyProject(`${projectId}`);

return (
<ProtectedRoute>
<div>
<MetaTags
title={TITLE_TEXT}
description={DESCRIPTION_TEXT}
type="website"
imageURL={IMAGE_URL}
/>
<NewProjectLayout>
<ProjectForm mode='create' initialData={myProjectData} projectId={projectId as string} />
</NewProjectLayout>
</div>
</ProtectedRoute>
)
}

export default EditProject
2 changes: 1 addition & 1 deletion client/src/pages/my-projects/new/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function NewProjectLayout({ children }: { children: React.ReactNo
</div>
</div>

<ProjectForm/>
<ProjectForm mode='create'/>
</Wrapper>
);
}
2 changes: 2 additions & 0 deletions client/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import myProjects from 'store/myProjects';
import { configureStore, combineReducers } from '@reduxjs/toolkit';
import type { ReducersMapObject } from '@reduxjs/toolkit';
import { createWrapper } from 'next-redux-wrapper';
import ProjectFormReducer from 'store/myProjects/form';

const staticReducers = {
'/action-map': actionMap,
'/funders': funders,
'/projects': projects,
'/dashboards/general-report': dashboardsGeneralReport,
'/myProjects': myProjects,
'/projectForm': ProjectFormReducer,
};

const asyncReducers = {};
Expand Down
75 changes: 75 additions & 0 deletions client/src/store/myProjects/form/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { HYDRATE } from 'next-redux-wrapper';
import { STORE_WRAPPER } from 'store';
import qs from 'query-string';

export interface ProjectFormState {
draftProject: {
name: string;
description: string;
logo: File | null;
contact_first_name: string;
contact_last_name: string;
website: string;
country_id: number | null;
state_id: number | null;
city: string;
leadership_demographics_other: string;
recipient_legal_status: string;
leadership_demographics: string[];
}
}

const initialState: ProjectFormState = {
draftProject:{
name: '',
description: '',
logo: null,
contact_first_name: '',
contact_last_name: '',
website: '',
country_id: null,
state_id: null,
city: '',
leadership_demographics_other: '',
recipient_legal_status: '',
leadership_demographics: [],
}

};

const slice = createSlice({
name: '/createProjectForm',
initialState,
reducers: {
// updateField: <K extends keyof ProjectFormState>(
// state: ProjectFormState,
// action: PayloadAction<{ field: K; value: ProjectFormState[K] }>
// ) => {
// state[action.payload.field] = action.payload.value;
// },
// setForm: (state, action: PayloadAction<ProjectFormState>) => {
// return action.payload;
// },

updateDraft: (state, action: PayloadAction<Partial<ProjectFormState['draftProject']>>) => {
state.draftProject = { ...state.draftProject, ...action.payload };
},

clearDraft: (state) => {
state.draftProject = initialState.draftProject;
}
},
extraReducers: {
[HYDRATE]: (state, action) => {
return {
...state,
...action.payload['/createProjectForm'],
};
},
},
});

export const { updateDraft, clearDraft } = slice.actions;

export default slice.reducer;

0 comments on commit efe1284

Please sign in to comment.