Skip to content

Commit

Permalink
Programs: new functionalities (#2270)
Browse files Browse the repository at this point in the history
* type definitions

* delete wiring

* edit profile changes

* clean update

* remove unused constructs

* programs container

* programs cards dark mode

* hide long program text

* program page

* remove extra details file

* program details page

* program skeleton

* program and milestone container

* temp milestones empty
  • Loading branch information
ap-justin authored Jul 20, 2023
1 parent d5eaa0e commit bf175b1
Show file tree
Hide file tree
Showing 27 changed files with 547 additions and 374 deletions.
6 changes: 3 additions & 3 deletions src/pages/Admin/Charity/CreateProgram/useSubmit.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SubmitHandler, useFormContext } from "react-hook-form";
import { FV } from "./types";
import { EndowmentProfileUpdate, Program } from "types/aws";
import { SemiPartial } from "types/utils";
import { ProfileUpdateMsg } from "services/types";
import { Program } from "types/aws";
import { useModalContext } from "contexts/ModalContext";
import { ImgLink } from "components/ImgEditor";
import { TxPrompt } from "components/Prompt";
Expand Down Expand Up @@ -55,7 +55,7 @@ export default function useSubmit() {
}
}

const updates: SemiPartial<EndowmentProfileUpdate, "id" | "owner"> = {
const updates: ProfileUpdateMsg = {
id,
owner,
program: [program],
Expand Down
20 changes: 10 additions & 10 deletions src/pages/Admin/Charity/EditProfile/Form.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FormHTMLAttributes } from "react";
import { Link } from "react-router-dom";
import { FormValues as FV } from "./types";
import { FV } from "./types";
import { UNSDG_NUMS } from "types/lists";
import ActivityCountries from "components/ActivityCountries";
import CountrySelector from "components/CountrySelector";
Expand Down Expand Up @@ -114,9 +114,9 @@ export default function Form({
<Label className="-mb-4" required>
Aligned SDG#
</Label>
<Selector<FV, "categories_sdgs", UNSDG_NUMS, true>
<Selector<FV, "sdgs", UNSDG_NUMS, true>
multiple
name="categories_sdgs"
name="sdgs"
options={sdgOptions}
classes={{ button: "field-input-admin" }}
/>
Expand Down Expand Up @@ -161,43 +161,43 @@ export default function Form({
<Group title="Social Media">
<Field<FV>
classes="field-admin"
name="social_media_url_facebook"
name="social_media_urls.facebook"
label="Facebook"
placeholder="https://facebook.com/"
/>
<Field<FV>
classes="field-admin"
name="social_media_url_linkedin"
name="social_media_urls.linkedin"
label="Linkedin"
placeholder="https://linkedin.com/"
/>
<Field<FV>
classes="field-admin"
name="social_media_url_twitter"
name="social_media_urls.twitter"
label="Twitter"
placeholder="https://twitter.com/"
/>
<Field<FV>
classes="field-admin"
name="social_media_url_discord"
name="social_media_urls.discord"
label="Discord"
placeholder="https://discord.com/"
/>
<Field<FV>
classes="field-admin"
name="social_media_url_instagram"
name="social_media_urls.instagram"
label="Instagram"
placeholder="https://instagram.com/"
/>
<Field<FV>
classes="field-admin"
name="social_media_url_youtube"
name="social_media_urls.youtube"
label="YouTube"
placeholder="https://youtube.com/"
/>
<Field<FV>
classes="field-admin"
name="social_media_url_tiktok"
name="social_media_urls.tiktok"
label="Tiktok"
placeholder="https://tiktok.com/"
/>
Expand Down
57 changes: 19 additions & 38 deletions src/pages/Admin/Charity/EditProfile/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { yupResolver } from "@hookform/resolvers/yup";
import { FormProvider, useForm } from "react-hook-form";
import { FlatFormValues, FormValues } from "./types";
import { Profile as TProfile, endow } from "services/types";
import { FV } from "./types";
import { Profile as TProfile } from "services/types";
import { EndowDesignation, EndowmentProfileUpdate } from "types/aws";
import { useProfileQuery } from "services/aws/aws";
import { FormError, FormSkeleton } from "components/admin";
import { adminRoutes } from "constants/routes";
Expand All @@ -13,6 +14,7 @@ import { getEndowDesignationLabelValuePair } from "./getEndowDesignationLabelVal
import { getSDGLabelValuePair } from "./getSDGLabelValuePair";
import { ops } from "./ops";
import { schema } from "./schema";
import { toProfileUpdate } from "./update";

export default function EditProfile() {
const { id } = useAdminContext(ops);
Expand All @@ -36,60 +38,39 @@ export default function EditProfile() {
}

function FormWithContext(props: TProfile) {
const { txResource } = useAdminContext(ops);
const { txResource, id, owner } = useAdminContext<"charity">(ops);

const { active_in_countries = [] } = props;
const designation = endow(props) ? props.endow_designation : "";
const sdgs = endow(props) ? props.sdgs : [];
// could just add to useForm.defaultValue - but not Partial here
const flatInitial: FlatFormValues = {
name: props.name,
categories_sdgs: sdgs,
endow_designation: designation,
hq_country: props.hq_country ?? "",
active_in_countries: active_in_countries,
image: props.image || "",
logo: props.logo || "",
kyc_donors_only: props.kyc_donors_only || false,
overview: props.overview ?? "",
url: props.url || "",
published: props.published || false,
registration_number: props.registration_number || "",
social_media_url_facebook: props.social_media_urls?.facebook || "",
social_media_url_linkedin: props.social_media_urls?.linkedin || "",
social_media_url_twitter: props.social_media_urls?.twitter || "",
social_media_url_discord: props.social_media_urls?.discord || "",
social_media_url_instagram: props.social_media_urls?.instagram || "",
social_media_url_youtube: props.social_media_urls?.youtube || "",
social_media_url_tiktok: props.social_media_urls?.tiktok || "",
street_address: props.street_address || "",
tagline: props.tagline,
};
const init: EndowmentProfileUpdate = toProfileUpdate({
type: "initial",
data: { ...props, id, owner },
});

const defaults: FormValues = {
...flatInitial,
const defaults: FV = {
...init,
image: {
name: "",
publicUrl: props.image ?? "",
preview: props.image ?? "",
},
logo: { name: "", publicUrl: props.logo ?? "", preview: props.logo ?? "" },
endow_designation: designation
? getEndowDesignationLabelValuePair(designation)
endow_designation: init.endow_designation
? getEndowDesignationLabelValuePair(
init.endow_designation as EndowDesignation
)
: { label: "", value: "" },
hq_country: { flag: "", name: props.hq_country ?? "", code: "" },
categories_sdgs: sdgs.map((x) => getSDGLabelValuePair(x, unsdgs[x].title)),
active_in_countries: active_in_countries.map((x) => ({
sdgs: init.sdgs.map((x) => getSDGLabelValuePair(x, unsdgs[x].title)),
active_in_countries: init.active_in_countries.map((x) => ({
label: x,
value: x,
})),

//meta
type: props.type,
initial: flatInitial,
initial: init,
};

const methods = useForm<FormValues>({
const methods = useForm<FV>({
defaultValues: defaults,
resolver: yupResolver(schema),
context: { isEndow: props.type === "endowment" },
Expand Down
22 changes: 12 additions & 10 deletions src/pages/Admin/Charity/EditProfile/schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { array, object, string } from "yup";
import { FormValues } from "./types";
import { FV } from "./types";
import { SchemaShape } from "schemas/types";
import { ImgLink } from "components/ImgEditor";
import { OptionType } from "components/Selector";
Expand All @@ -23,9 +23,9 @@ const fileObj = object().shape<SchemaShape<ImgLink>>({
});

//construct strict shape to avoid hardcoding shape keys
const shape: SchemaShape<FormValues> = {
const shape: SchemaShape<FV> = {
//not required for ASTs
categories_sdgs: array()
sdgs: array()
.max(MAX_SDGS, `maximum ${MAX_SDGS} selections allowed`)
.when("$isEndow", {
is: true,
Expand All @@ -48,13 +48,15 @@ const shape: SchemaShape<FormValues> = {
}),
name: requiredString,
active_in_countries: array(),
social_media_url_facebook: url,
social_media_url_twitter: url,
social_media_url_linkedin: url,
social_media_url_discord: url,
social_media_url_instagram: url,
social_media_url_youtube: url,
social_media_url_tiktok: url,
social_media_urls: object().shape<SchemaShape<FV["social_media_urls"]>>({
facebook: url,
twitter: url,
linkedin: url,
discord: url,
instagram: url,
youtube: url,
tiktok: url,
}),
};

export const schema = object().shape(shape);
59 changes: 11 additions & 48 deletions src/pages/Admin/Charity/EditProfile/types.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,19 @@
import { Except } from "type-fest";
import { OverrideProperties } from "type-fest";
import { Profile } from "services/types";
import { EndowmentProfileUpdate } from "types/aws";
import { Country } from "types/countries";
import { UNSDG_NUMS } from "types/lists";
import { ImgLink } from "components/ImgEditor";
import { OptionType } from "components/Selector";

type K = keyof EndowmentProfileUpdate;
const _logo: K = "logo";
const _img: K = "image";
const _country: K = "hq_country";
const _activity_countries: K = "active_in_countries";
const _sdgs: K = "categories_sdgs";
const _general: K = "categories_general";
const _id: K = "id";
const _tier: K = "tier";
const _owner: K = "owner";
const _npo_type: K = "endow_designation";
const _contributor_verification_required: K =
"contributor_verification_required";

export type FlatFormValues = Except<
export type FV = OverrideProperties<
EndowmentProfileUpdate,
/** to flatten */
/** don't include for now */
| typeof _general
/** not editable fields*/
| typeof _id
| typeof _tier
| typeof _owner
| typeof _contributor_verification_required
| "program"
| "program_id"
>;

export type FormValues = Omit<
FlatFormValues,
| typeof _logo
| typeof _img
| typeof _country
| typeof _sdgs
| typeof _activity_countries
| typeof _npo_type
> & {
[_npo_type]: OptionType<string>;
[_logo]: ImgLink;
[_img]: ImgLink;
[_country]: Country;
[_sdgs]: OptionType<UNSDG_NUMS>[];
[_activity_countries]: OptionType<string>[];

//meta
type: Profile["type"];
initial: FlatFormValues;
};
{
endow_designation: OptionType<string>;
logo: ImgLink;
image: ImgLink;
hq_country: Country;
sdgs: OptionType<UNSDG_NUMS>[];
active_in_countries: OptionType<string>[];
}
> & { type: Profile["type"]; initial: EndowmentProfileUpdate };
69 changes: 69 additions & 0 deletions src/pages/Admin/Charity/EditProfile/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Except } from "type-fest";
import { FV } from "./types";
import { Profile, endow } from "services/types";
import { EndowmentProfileUpdate } from "types/aws";

type RequiredFields = Pick<EndowmentProfileUpdate, "id" | "owner">;
type Arg =
| {
type: "initial";
data: Profile & RequiredFields;
}
| {
type: "final";
data: Except<FV, "id" | "owner" | "initial" | "type"> & RequiredFields;
urls: { image: string; logo: string };
};

export function toProfileUpdate(arg: Arg): EndowmentProfileUpdate {
if (arg.type === "initial") {
const { data: d } = arg;
return {
id: d.id,
owner: d.owner,
active_in_countries: d.active_in_countries ?? [],
categories: { sdgs: d.sdgs ?? [], general: [] },
charity_navigator_rating: "",
contact_email: d.contact_email ?? "",
contributor_verification_required:
d.contributor_verification_required ?? false,
endow_designation: endow(d) ? d.endow_designation : "",
hq_country: d.hq_country ?? "",
image: d.image ?? "",
kyc_donors_only: d.kyc_donors_only ?? false,
logo: d.logo ?? "",
name: d.name ?? "",
overview: d.overview ?? "",
program: [], //program is updated in /create-program
program_id: "",
published: d.published ?? false,
registration_number: d.registration_number ?? "",
sdgs: d.sdgs ?? [],
social_media_urls: {
facebook: d.social_media_urls?.facebook ?? "",
instagram: d.social_media_urls?.instagram ?? "",
linkedin: d.social_media_urls?.linkedin ?? "",
twitter: d.social_media_urls?.twitter ?? "",
discord: d.social_media_urls?.discord ?? "",
youtube: d.social_media_urls?.youtube ?? "",
tiktok: d.social_media_urls?.tiktok ?? "",
},
street_address: d.street_address ?? "",
tagline: d.tagline ?? "",
tier: 1,
url: d.url ?? "",
};
}

const { data: fv, urls } = arg;
return {
...fv,
program: [], //program is updated in /create-program
image: urls.image,
logo: urls.logo,
hq_country: fv.hq_country.name,
endow_designation: fv.endow_designation.value,
sdgs: fv.sdgs.map((opt) => opt.value),
active_in_countries: fv.active_in_countries.map((opt) => opt.value),
};
}
Loading

0 comments on commit bf175b1

Please sign in to comment.