Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/craft settings program collection selector add program status select #487

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
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
45 changes: 25 additions & 20 deletions src/components/craft/CraftResolver.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useApolloClient } from '@apollo/client'
import { gql } from '@apollo/client'
import { gql, useApolloClient } from '@apollo/client'
import * as CraftElement from 'lodestar-app-element/src/components/common/CraftElement'
import { useAuth } from 'lodestar-app-element/src/contexts/AuthContext'
import { useIntl } from 'react-intl'
Expand All @@ -12,109 +11,115 @@ export const useResolver = () => {
const { currentMemberId } = useAuth()
const { formatMessage } = useIntl()
CraftElement.CraftMemberCollection.craft = {
displayName: formatMessage({ id: 'craft.resolver.MemberCollectionSettings', defaultMessage: '會員' }),
displayName: formatMessage({ id: 'craft.resolver.MemberCollectionSettings', defaultMessage: 'Member' }),
related: {
settings: withResponsive(CraftSetting.MemberCollectionSettings),
},
}
CraftElement.CraftProgramCollection.craft = {
displayName: formatMessage({ id: 'craft.resolver.ProgramCollectionSettings', defaultMessage: '課程' }),
displayName: formatMessage({ id: 'craft.resolver.ProgramCollectionSettings', defaultMessage: 'Program' }),
related: {
settings: withResponsive(CraftSetting.ProgramCollectionSettings),
},
}
CraftElement.CraftProgramContentCollection.craft = {
displayName: formatMessage({ id: 'craft.resolver.ProgramContentCollectionSettings', defaultMessage: '課程單元' }),
displayName: formatMessage({
id: 'craft.resolver.ProgramContentCollectionSettings',
defaultMessage: 'Program Content',
}),
related: {
settings: withResponsive(CraftSetting.ProgramContentCollectionSettings),
},
}
CraftElement.CraftProgramPackageCollection.craft = {
displayName: formatMessage({ id: 'craft.resolver.ProgramPackageCollectionSettings', defaultMessage: '課程組合' }),
displayName: formatMessage({
id: 'craft.resolver.ProgramPackageCollectionSettings',
defaultMessage: 'Program Package',
}),
related: {
settings: withResponsive(CraftSetting.ProgramPackageCollectionSettings),
},
}
CraftElement.CraftActivityCollection.craft = {
displayName: formatMessage({ id: 'craft.resolver.ActivityCollectionSettings', defaultMessage: '活動' }),
displayName: formatMessage({ id: 'craft.resolver.ActivityCollectionSettings', defaultMessage: 'Activity' }),
related: {
settings: withResponsive(CraftSetting.ActivityCollectionSettings),
},
}
CraftElement.CraftProjectCollection.craft = {
displayName: formatMessage({ id: 'craft.resolver.ProjectCollectionSettings', defaultMessage: '專案' }),
displayName: formatMessage({ id: 'craft.resolver.ProjectCollectionSettings', defaultMessage: 'Project' }),
related: {
settings: withResponsive(CraftSetting.ProjectCollectionSettings),
},
}
CraftElement.CraftPostCollection.craft = {
displayName: formatMessage({ id: 'craft.resolver.PostCollectionSettings', defaultMessage: '文章' }),
displayName: formatMessage({ id: 'craft.resolver.PostCollectionSettings', defaultMessage: 'Post' }),
related: {
settings: withResponsive(CraftSetting.PostCollectionSettings),
},
}
CraftElement.CraftSection.craft = {
displayName: formatMessage({ id: 'craft.resolver.SectionSettings', defaultMessage: '區塊' }),
displayName: formatMessage({ id: 'craft.resolver.SectionSettings', defaultMessage: 'Section' }),
related: {
settings: withResponsive(CraftSetting.SectionSettings),
},
}
CraftElement.CraftButton.craft = {
displayName: formatMessage({ id: 'craft.resolver.ButtonSettings', defaultMessage: '按鈕' }),
displayName: formatMessage({ id: 'craft.resolver.ButtonSettings', defaultMessage: 'Button' }),
related: {
settings: withResponsive(CraftSetting.ButtonSettings),
},
}
CraftElement.CraftCard.craft = {
displayName: formatMessage({ id: 'craft.resolver.CardSettings', defaultMessage: '卡片' }),
displayName: formatMessage({ id: 'craft.resolver.CardSettings', defaultMessage: 'Card' }),
related: {
settings: withResponsive(CraftSetting.CardSettings),
},
}
CraftElement.CraftCarousel.craft = {
displayName: formatMessage({ id: 'craft.resolver.CarouselSettings', defaultMessage: '輪播' }),
displayName: formatMessage({ id: 'craft.resolver.CarouselSettings', defaultMessage: 'Carousel' }),
related: {
settings: withResponsive(CraftSetting.CarouselSettings),
},
}
CraftElement.CraftCollapse.craft = {
displayName: formatMessage({ id: 'craft.resolver.CollapseSettings', defaultMessage: '折疊' }),
displayName: formatMessage({ id: 'craft.resolver.CollapseSettings', defaultMessage: 'Collapse' }),
related: {
settings: withResponsive(CraftSetting.CollapseSettings),
},
}
CraftElement.CraftImage.craft = {
displayName: formatMessage({ id: 'craft.resolver.ImageSettings', defaultMessage: '圖片' }),
displayName: formatMessage({ id: 'craft.resolver.ImageSettings', defaultMessage: 'Image' }),
related: {
settings: withResponsive(CraftSetting.ImageSettings),
},
}
CraftElement.CraftLayout.craft = {
displayName: formatMessage({ id: 'craft.resolver.LayoutSettings', defaultMessage: '佈局' }),
displayName: formatMessage({ id: 'craft.resolver.LayoutSettings', defaultMessage: 'Layout' }),
related: {
settings: withResponsive(CraftSetting.LayoutSettings),
},
}
CraftElement.CraftParagraph.craft = {
displayName: formatMessage({ id: 'craft.resolver.ParagraphSettings', defaultMessage: '段落' }),
displayName: formatMessage({ id: 'craft.resolver.ParagraphSettings', defaultMessage: 'Paragraph' }),
related: {
settings: withResponsive(CraftSetting.ParagraphSettings),
},
}
CraftElement.CraftTitle.craft = {
displayName: formatMessage({ id: 'craft.resolver.TitleSettings', defaultMessage: '標題' }),
displayName: formatMessage({ id: 'craft.resolver.TitleSettings', defaultMessage: 'Title' }),
related: {
settings: withResponsive(CraftSetting.TitleSettings),
},
}
CraftElement.CraftEmbedded.craft = {
displayName: formatMessage({ id: 'craft.resolver.EmbeddedSettings', defaultMessage: '嵌入' }),
displayName: formatMessage({ id: 'craft.resolver.EmbeddedSettings', defaultMessage: 'Embed' }),
related: {
settings: withResponsive(CraftSetting.EmbeddedSettings),
},
}
CraftElement.CraftAIBot.craft = {
displayName: formatMessage({ id: 'craft.resolver.AIBotSettings', defaultMessage: '嵌入' }),
displayName: formatMessage({ id: 'craft.resolver.AIBotSettings', defaultMessage: 'AI BOT' }),
related: {
settings: withResponsive(CraftSetting.AIBotSettings),
},
Expand Down
61 changes: 42 additions & 19 deletions src/components/program/ProgramCollectionSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,58 @@
import { useQuery } from '@apollo/client'
import { Button, Form, InputNumber, Select } from 'antd'
import { gql } from '@apollo/client'
import { ProgramCollectionProps } from 'lodestar-app-element/src/components/collections/ProgramCollection'
import { useIntl } from 'react-intl'
import hasura from '../../hasura'
import { craftPageMessages } from '../../helpers/translation'
import { commonMessages, craftPageMessages } from '../../helpers/translation'
import { useAppMembershipCard } from '../../hooks/card'
import { useProgramList } from '../../hooks/program'
import { CraftSettingLabel } from '../../pages/CraftPageAdminPage/CraftSettingsPanel'
import ProgramCategorySelect from './ProgramCategorySelect'
import ProgramTagSelect from './ProgramTagSelect'
import programMessages from './translation'

type ProgramSourceOptions = ProgramCollectionProps['source']
const ProgramCollectionSelector: React.FC<{
withOrderSelector?: boolean
value?: ProgramSourceOptions
onChange?: (value: ProgramSourceOptions) => void
value?: ProgramCollectionProps['source']
onChange?: (value: ProgramCollectionProps['source']) => void
}> = ({ withOrderSelector, value = { from: 'publishedAt' }, onChange }) => {
const { formatMessage } = useIntl()
const { data } = useQuery<hasura.GET_PROGRAM_ID_LIST>(GET_PROGRAM_ID_LIST)
const programOptions = data?.program.map(p => ({ id: p.id, title: p.title })) || []
const { programs } = useProgramList()
const { membershipCards } = useAppMembershipCard()

return (
<div>
<Form.Item label={formatMessage(programMessages.ProgramCollectionSelector.programStatus)}>
<Select
value={value.programStatus || 'public'}
onChange={programStatus =>
onChange?.({
...value,
programStatus,
membershipCardId: programStatus === 'membership_card' ? membershipCards[0].id : undefined,
})
}
>
<Select.Option value="public">{formatMessage(commonMessages.status.publiclyPublish)}</Select.Option>
<Select.Option value="private">{formatMessage(commonMessages.status.privatelyPublish)}</Select.Option>
<Select.Option value="membership_card">
{formatMessage(programMessages.ProgramCollectionSelector.membershipCard)}
</Select.Option>
</Select>
</Form.Item>
{value.programStatus === 'membership_card' && (
<Form.Item label={formatMessage(programMessages.ProgramCollectionSelector.membershipCard)}>
<Select
value={value.membershipCardId || membershipCards[0].id}
onChange={membershipCardId => onChange?.({ ...value, membershipCardId })}
>
{membershipCards.map(card => (
<Select.Option key={card.id} value={card.id}>
{card.title}
</Select.Option>
))}
</Select>
</Form.Item>
)}

<Form.Item
label={
<CraftSettingLabel>{formatMessage(programMessages.ProgramCollectionSelector.ruleOfSort)}</CraftSettingLabel>
Expand Down Expand Up @@ -147,7 +179,7 @@ const ProgramCollectionSelector: React.FC<{
allowClear
placeholder={formatMessage(programMessages.ProgramCollectionSelector.choiceData)}
value={programId}
options={programOptions.map(({ id, title }) => ({ key: id, value: id, label: title }))}
options={programs.map(({ id, title }) => ({ key: id, value: id, label: title }))}
onChange={selectedProgramId =>
selectedProgramId &&
onChange?.({
Expand Down Expand Up @@ -180,13 +212,4 @@ const ProgramCollectionSelector: React.FC<{
)
}

const GET_PROGRAM_ID_LIST = gql`
query GET_PROGRAM_ID_LIST {
program(where: { published_at: { _lt: "now()" } }) {
id
title
}
}
`

export default ProgramCollectionSelector
2 changes: 2 additions & 0 deletions src/components/program/translation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const programMessages = {
defaultTagName: { id: 'program.ProgramCollectionSelector.defaultTagName', defaultMessage: '預設標籤' },
dataDisplay: { id: 'program.ProgramCollectionSelector.dataDisplay', defaultMessage: '資料顯示' },
addItem: { id: 'program.ProgramCollectionSelector.addItem', defaultMessage: '新增項目' },
membershipCard: { id: 'program.ProgramCollectionSelector.membershipCard', defaultMessage: 'Membership Card' },
programStatus: { id: 'program.ProgramCollectionSelector.programStatus', defaultMessage: 'Program Status' },
}),
ProgramPackageSelector: defineMessages({
allProgramPackage: { id: 'program.ProgramPackageSelector.allProgramPackage', defaultMessage: '全部課程組合' },
Expand Down
23 changes: 18 additions & 5 deletions src/hasura.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135142,6 +135142,7 @@ export type user = {
name: Scalars['String'];
/** An object relationship */
org?: Maybe<org>;
/** org_id */
org_id: Scalars['String'];
passhash?: Maybe<Scalars['String']>;
phone?: Maybe<Scalars['String']>;
Expand Down Expand Up @@ -135267,6 +135268,7 @@ export type user_insert_input = {
metadata?: InputMaybe<Scalars['jsonb']>;
name?: InputMaybe<Scalars['String']>;
org?: InputMaybe<org_obj_rel_insert_input>;
/** org_id */
org_id?: InputMaybe<Scalars['String']>;
passhash?: InputMaybe<Scalars['String']>;
phone?: InputMaybe<Scalars['String']>;
Expand All @@ -135287,6 +135289,7 @@ export type user_max_fields = {
id?: Maybe<Scalars['String']>;
logined_at?: Maybe<Scalars['timestamptz']>;
name?: Maybe<Scalars['String']>;
/** org_id */
org_id?: Maybe<Scalars['String']>;
passhash?: Maybe<Scalars['String']>;
phone?: Maybe<Scalars['String']>;
Expand All @@ -135306,6 +135309,7 @@ export type user_min_fields = {
id?: Maybe<Scalars['String']>;
logined_at?: Maybe<Scalars['timestamptz']>;
name?: Maybe<Scalars['String']>;
/** org_id */
org_id?: Maybe<Scalars['String']>;
passhash?: Maybe<Scalars['String']>;
phone?: Maybe<Scalars['String']>;
Expand Down Expand Up @@ -135842,6 +135846,7 @@ export type user_set_input = {
logined_at?: InputMaybe<Scalars['timestamptz']>;
metadata?: InputMaybe<Scalars['jsonb']>;
name?: InputMaybe<Scalars['String']>;
/** org_id */
org_id?: InputMaybe<Scalars['String']>;
passhash?: InputMaybe<Scalars['String']>;
phone?: InputMaybe<Scalars['String']>;
Expand Down Expand Up @@ -135869,6 +135874,7 @@ export type user_stream_cursor_value_input = {
logined_at?: InputMaybe<Scalars['timestamptz']>;
metadata?: InputMaybe<Scalars['jsonb']>;
name?: InputMaybe<Scalars['String']>;
/** org_id */
org_id?: InputMaybe<Scalars['String']>;
passhash?: InputMaybe<Scalars['String']>;
phone?: InputMaybe<Scalars['String']>;
Expand Down Expand Up @@ -149248,11 +149254,6 @@ export type GET_PROGRAM_CATEGORIESVariables = Exact<{ [key: string]: never; }>;

export type GET_PROGRAM_CATEGORIES = { __typename?: 'query_root', category: Array<{ __typename?: 'category', id: string, name: string }> };

export type GET_PROGRAM_ID_LISTVariables = Exact<{ [key: string]: never; }>;


export type GET_PROGRAM_ID_LIST = { __typename?: 'query_root', program: Array<{ __typename?: 'program', id: any, title: string }> };

export type GET_PROGRAM_CONTENT_ID_LISTVariables = Exact<{ [key: string]: never; }>;


Expand Down Expand Up @@ -150090,6 +150091,13 @@ export type GET_ENROLLED_CARDSVariables = Exact<{

export type GET_ENROLLED_CARDS = { __typename?: 'query_root', card_enrollment: Array<{ __typename?: 'card_enrollment', updated_at?: any | null, card?: { __typename?: 'card', id: any, title: string, description: string, template: string } | null }> };

export type GetMembershipCardVariables = Exact<{
appId: Scalars['String'];
}>;


export type GetMembershipCard = { __typename?: 'query_root', card: Array<{ __typename?: 'card', id: any, title: string }> };

export type GET_PRODUCT_CHANNEL_INFOVariables = Exact<{
appId?: InputMaybe<Scalars['String']>;
productId?: InputMaybe<Scalars['String']>;
Expand Down Expand Up @@ -150986,6 +150994,11 @@ export type UPDATE_PROGRAM_CONTENT_AUDIOSVariables = Exact<{

export type UPDATE_PROGRAM_CONTENT_AUDIOS = { __typename?: 'mutation_root', delete_program_content_audio?: { __typename?: 'program_content_audio_mutation_response', affected_rows: number } | null, insert_program_content_audio?: { __typename?: 'program_content_audio_mutation_response', affected_rows: number } | null };

export type GetProgramListVariables = Exact<{ [key: string]: never; }>;


export type GetProgramList = { __typename?: 'query_root', program: Array<{ __typename?: 'program', id: any, title: string }> };

export type GET_PROGRAM_PACKAGE_COLLECTIONVariables = Exact<{ [key: string]: never; }>;


Expand Down
20 changes: 20 additions & 0 deletions src/hooks/card.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useQuery } from '@apollo/client'
import { gql } from '@apollo/client'
import { useApp } from 'lodestar-app-element/src/contexts/AppContext'
import hasura from '../hasura'

export const useEnrolledMembershipCardIds = (memberId: string) => {
Expand Down Expand Up @@ -117,3 +118,22 @@ export const useEnrolledMembershipCards = (memberId: string) => {
refetchMembershipCards: refetch,
}
}

export const useAppMembershipCard = () => {
const { id: appId } = useApp()
const { data } = useQuery<hasura.GetMembershipCard, hasura.GetMembershipCardVariables>(
gql`
query GetMembershipCard($appId: String!) {
card(where: { app_id: { _eq: $appId } }) {
id
title
}
}
`,
{ variables: { appId } },
)
const membershipCards = data?.card.map(card => ({ id: card.id, title: card.title })) || []
return {
membershipCards,
}
}
15 changes: 15 additions & 0 deletions src/hooks/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -919,3 +919,18 @@ export const useProgramContentActions = (programContentId: string) => {
},
}
}

export const useProgramList = () => {
const { data } = useQuery<hasura.GetProgramList>(gql`
query GetProgramList {
program(where: { published_at: { _lt: "now()" }, is_deleted: { _eq: false } }) {
id
title
}
}
`)
const programs = data?.program.map(p => ({ id: p.id, title: p.title })) || []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

programs could add type

type programs = {
  id: string;
  title: string;
};

return {
programs,
}
}
Loading
Loading