From a9ec21235ad1485c53d45dcedb11abd0faac745b Mon Sep 17 00:00:00 2001 From: Max Wu Date: Mon, 6 May 2024 21:35:16 -1000 Subject: [PATCH 1/5] Add production docker-compose --- hasura/.gitignore | 2 +- hasura/docker-compose.dev.yml | 47 +++++++++++++++++++++++++++++++++++ hasura/docker-compose.yml | 35 ++++---------------------- 3 files changed, 53 insertions(+), 31 deletions(-) create mode 100644 hasura/docker-compose.dev.yml diff --git a/hasura/.gitignore b/hasura/.gitignore index 7748252..a7adbe4 100644 --- a/hasura/.gitignore +++ b/hasura/.gitignore @@ -1,2 +1,2 @@ -.env +.env* /db_data \ No newline at end of file diff --git a/hasura/docker-compose.dev.yml b/hasura/docker-compose.dev.yml new file mode 100644 index 0000000..9cc5d76 --- /dev/null +++ b/hasura/docker-compose.dev.yml @@ -0,0 +1,47 @@ +version: "3.6" +services: + postgres: + image: postgres:12 + restart: always + volumes: + - db_data:/var/lib/postgresql/data + ports: + - "5432:5432" + environment: + POSTGRES_PASSWORD: postgrespassword + graphql-engine: + image: hasura/graphql-engine:v2.16.0 + ports: + - "8080:8080" + depends_on: + - "postgres" + restart: always + environment: + ## postgres database to store Hasura metadata + HASURA_GRAPHQL_METADATA_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres + ## this env var can be used to add the above postgres database to Hasura as a data source. this can be removed/updated based on your needs + PG_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres + HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres + ## enable the console served by server + HASURA_GRAPHQL_ENABLE_CONSOLE: "true" # set to "false" to disable console + ## enable debugging mode. It is recommended to disable this in production + HASURA_GRAPHQL_DEV_MODE: "true" + HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log + ## uncomment next line to set an admin secret + HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey + ## Hasura JWT Secret + HASURA_GRAPHQL_JWT_SECRET: "${HASURA_GRAPHQL_JWT_SECRET}" + ## Unauthorized role + HASURA_GRAPHQL_UNAUTHORIZED_ROLE: "public" + + ## CRON Webhook URL + CANOPY_CRON_WEBHOOK_URL: "${CANOPY_CRON_WEBHOOK_URL}" + ## CRON Client Key + CANOPY_CRON_CLIENT_KEY: "${CANOPY_CRON_CLIENT_KEY}" + + ## Event Webhook URL + CANOPY_EVENT_WEBHOOK_URL: "${CANOPY_EVENT_WEBHOOK_URL}" + ## Event Client Key + CANOPY_EVENT_CLIENT_KEY: "${CANOPY_EVENT_CLIENT_KEY}" +volumes: + db_data: diff --git a/hasura/docker-compose.yml b/hasura/docker-compose.yml index 9cc5d76..fe136ea 100644 --- a/hasura/docker-compose.yml +++ b/hasura/docker-compose.yml @@ -4,11 +4,11 @@ services: image: postgres:12 restart: always volumes: - - db_data:/var/lib/postgresql/data + - canopy_prod_db:/var/lib/postgresql/data ports: - "5432:5432" environment: - POSTGRES_PASSWORD: postgrespassword + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" graphql-engine: image: hasura/graphql-engine:v2.16.0 ports: @@ -16,32 +16,7 @@ services: depends_on: - "postgres" restart: always - environment: - ## postgres database to store Hasura metadata - HASURA_GRAPHQL_METADATA_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres - ## this env var can be used to add the above postgres database to Hasura as a data source. this can be removed/updated based on your needs - PG_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres - HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres - ## enable the console served by server - HASURA_GRAPHQL_ENABLE_CONSOLE: "true" # set to "false" to disable console - ## enable debugging mode. It is recommended to disable this in production - HASURA_GRAPHQL_DEV_MODE: "true" - HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log - ## uncomment next line to set an admin secret - HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey - ## Hasura JWT Secret - HASURA_GRAPHQL_JWT_SECRET: "${HASURA_GRAPHQL_JWT_SECRET}" - ## Unauthorized role - HASURA_GRAPHQL_UNAUTHORIZED_ROLE: "public" - - ## CRON Webhook URL - CANOPY_CRON_WEBHOOK_URL: "${CANOPY_CRON_WEBHOOK_URL}" - ## CRON Client Key - CANOPY_CRON_CLIENT_KEY: "${CANOPY_CRON_CLIENT_KEY}" - - ## Event Webhook URL - CANOPY_EVENT_WEBHOOK_URL: "${CANOPY_EVENT_WEBHOOK_URL}" - ## Event Client Key - CANOPY_EVENT_CLIENT_KEY: "${CANOPY_EVENT_CLIENT_KEY}" + env_file: + - .env.prod volumes: - db_data: + canopy_prod_db: From ef11654d0dcfd5463d558ee42888b1087c7c80ec Mon Sep 17 00:00:00 2001 From: Max Wu Date: Tue, 7 May 2024 09:00:59 -1000 Subject: [PATCH 2/5] Edit docker compose --- hasura/docker-compose.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hasura/docker-compose.yml b/hasura/docker-compose.yml index fe136ea..83eca98 100644 --- a/hasura/docker-compose.yml +++ b/hasura/docker-compose.yml @@ -7,8 +7,8 @@ services: - canopy_prod_db:/var/lib/postgresql/data ports: - "5432:5432" - environment: - POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" + env_file: + - .env.prod graphql-engine: image: hasura/graphql-engine:v2.16.0 ports: @@ -18,5 +18,6 @@ services: restart: always env_file: - .env.prod + volumes: canopy_prod_db: From c4b8a6fbc601b21f63227e4b6b43527e400427be Mon Sep 17 00:00:00 2001 From: Max Wu Date: Tue, 7 May 2024 12:56:55 -1000 Subject: [PATCH 3/5] Use node 16 --- .github/workflows/dev.yml | 2 +- .github/workflows/prod.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index bc51e7d..73fe3bc 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -18,7 +18,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v1 with: - node-version: 14.x + node-version: 16.x cache: "npm" - name: Install Hasura CLI diff --git a/.github/workflows/prod.yml b/.github/workflows/prod.yml index fa0703a..2b46836 100644 --- a/.github/workflows/prod.yml +++ b/.github/workflows/prod.yml @@ -18,7 +18,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v1 with: - node-version: 14.x + node-version: 16.x cache: "npm" - name: Install Hasura CLI From 6cd54c0ec0b4154e77e060bb77a095a8a92f2104 Mon Sep 17 00:00:00 2001 From: Max Wu Date: Wed, 26 Jun 2024 09:43:18 -0700 Subject: [PATCH 4/5] Add community guidelines settings --- web/components/EditProfileListing.tsx | 48 ++++++++++++- web/components/admin/SetPrivacySettings.tsx | 72 +++++++++++++------ web/components/atomic/CheckBox.tsx | 3 +- .../space-homepage/SpaceLandingPage.tsx | 4 +- web/hooks/usePrivacySettings.ts | 39 ---------- web/hooks/useSpaceAttributes.ts | 30 ++++++++ web/hooks/useValidateProfileCompletion.ts | 15 +++- web/lib/profileAttributes.ts | 2 + web/lib/spaceAttributes.ts | 6 +- web/pages/api/invite/joinProgram.ts | 7 -- .../space/[slug]/join/[inviteLinkId].tsx | 15 +--- 11 files changed, 156 insertions(+), 85 deletions(-) delete mode 100644 web/hooks/usePrivacySettings.ts create mode 100644 web/hooks/useSpaceAttributes.ts diff --git a/web/components/EditProfileListing.tsx b/web/components/EditProfileListing.tsx index 695973c..a2394a8 100644 --- a/web/components/EditProfileListing.tsx +++ b/web/components/EditProfileListing.tsx @@ -18,6 +18,10 @@ import { EditResponse } from "./edit-profile/EditResponse"; import { ProfileSocialsDisplay } from "./edit-socials-info/ProfileSocialsDisplay"; import { ProfileSocialsModal } from "./edit-socials-info/ProfileSocialsModal"; import PublishedToggleSwitch from "./PublishedToggleSwitch"; +import { useSpaceAttributes } from "../hooks/useSpaceAttributes"; +import { CheckBox } from "./atomic/CheckBox"; +import { handleError } from "../lib/error"; +import toast from "react-hot-toast"; function EditProfileImage() { const { currentProfile } = useCurrentProfile(); @@ -53,9 +57,15 @@ interface EditProfileListingProps { export function EditProfileListing(props: EditProfileListingProps) { const { showPublishedToggle = true } = props; - const { currentProfile, currentProfileHasRole } = useCurrentProfile(); + const { + currentProfile, + currentProfileHasRole, + profileAttributes, + updateProfileAttributes, + } = useCurrentProfile(); const { currentSpace } = useCurrentSpace(); const { userData } = useUserData(); + const { attributes } = useSpaceAttributes(); const [socialsOpened, socialsHandlers] = useDisclosure(false); @@ -78,7 +88,43 @@ export function EditProfileListing(props: EditProfileListingProps) { profileListingId={currentProfile.profile_listing?.id ?? ""} /> )} +
+ {attributes?.communityGuidelinesUrl && ( + <> + + I agree to the{" "} + + community guidelines + + + } + checked={profileAttributes.agreedToCommunityGuidelines} + onChange={(e) => { + const newVal = e.target?.checked ?? false; + + toast.promise( + updateProfileAttributes({ + agreedToCommunityGuidelines: newVal, + }), + { + loading: "Loading", + success: `${newVal ? "Agreed" : "Disagreed"} to guidelines`, + error: (err) => err.message, + } + ); + }} + /> +
+ + )}
diff --git a/web/components/admin/SetPrivacySettings.tsx b/web/components/admin/SetPrivacySettings.tsx index 0534c11..a52fa85 100644 --- a/web/components/admin/SetPrivacySettings.tsx +++ b/web/components/admin/SetPrivacySettings.tsx @@ -2,37 +2,36 @@ import { useEffect, useMemo, useState } from "react"; import toast from "react-hot-toast"; -import { Button, Text } from "../../components/atomic"; +import { Button, Input, Text } from "../../components/atomic"; import { useUpdateSpaceAttributesMutation, useUpdateSpaceMutation, } from "../../generated/graphql"; import { useCurrentSpace } from "../../hooks/useCurrentSpace"; -import { - PrivacySettings, - usePrivacySettings, -} from "../../hooks/usePrivacySettings"; +import { useSpaceAttributes } from "../../hooks/useSpaceAttributes"; import { useSaveChangesState } from "../../hooks/useSaveChangesState"; import { CheckBox } from "../atomic/CheckBox"; +import { TextInput } from "../inputs/TextInput"; +import { SpaceAttributes } from "../../lib/spaceAttributes"; export function SetPrivacySettings() { const { currentSpace } = useCurrentSpace(); - const { privacySettings } = usePrivacySettings(); + const { attributes } = useSpaceAttributes(); - const [settings, setSettings] = useState(); + const [attributesState, setAttributesState] = useState(); const { mustSave, setMustSave } = useSaveChangesState(); useEffect(() => { - if (privacySettings) { - setSettings(privacySettings); + if (attributes) { + setAttributesState(attributes); } - }, [privacySettings]); + }, [attributes]); const [loading, setLoading] = useState(false); const [_, updateSpaceAttributes] = useUpdateSpaceAttributesMutation(); - if (!settings) { + if (!attributesState) { return null; } @@ -48,24 +47,24 @@ export function SetPrivacySettings() {
{ const newVal = e.target?.checked ?? false; setMustSave(true); - setSettings({ ...settings, public: newVal }); + setAttributesState({ ...attributesState, public: newVal }); }} />
{ const newVal = e.target?.checked ?? false; setMustSave(true); - setSettings({ - ...settings, + setAttributesState({ + ...attributesState, allowOnlyPublicMembersToViewProfiles: newVal, }); }} @@ -74,19 +73,52 @@ export function SetPrivacySettings() {
{ const newVal = e.target?.checked ?? false; setMustSave(true); - setSettings({ - ...settings, + setAttributesState({ + ...attributesState, optUsersInToMatchesByDefault: newVal, }); }} /> +
+ { + const newVal = e.target.value; + + setMustSave(true); + setAttributesState({ + ...attributesState, + domainWhitelists: newVal + ? newVal.split(",").map((x) => x.trim()) + : null, + }); + }} + /> + +
+ { + const newVal = e.target.value; + setMustSave(true); + setAttributesState({ + ...attributesState, + communityGuidelinesUrl: newVal || null, + }); + }} + /> +
+ {/*
{JSON.stringify(settings, null, 2)}
*/}
))}
- ) : privacySettings?.allowOnlyPublicMembersToViewProfiles && + ) : attributes?.allowOnlyPublicMembersToViewProfiles && !currentProfile?.profile_listing?.public && !adminBypass ? ( <> diff --git a/web/lib/profileAttributes.ts b/web/lib/profileAttributes.ts index 8ec86f9..94b7da2 100644 --- a/web/lib/profileAttributes.ts +++ b/web/lib/profileAttributes.ts @@ -2,7 +2,7 @@ export type ProfileAttributes = { enableChatIntros: boolean; agreedToCommunityGuidelines: boolean; }; -const DEFAULT_PROFILE_ATTRIBUTES: ProfileAttributes = { +export const DEFAULT_PROFILE_ATTRIBUTES: ProfileAttributes = { enableChatIntros: false, agreedToCommunityGuidelines: false, };