diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index e91dd6aa..72bc24d0 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -241,6 +241,8 @@ "음소거": "Mute", "음소거 해제": "Unmute", "발언자는 최대 {{MAX_SPEAKER_LEN}}자까지 입력할 수 있습니다.": "Speaker can be up to {{MAX_SPEAKER_LEN}} characters.", + "템플릿을 불러오는 중입니다...": "Loading templates...", + "템플릿을 불러오지 못했습니다. 잠시 후 다시 시도해주세요.": "Failed to load templates. Please try again later.", "400 잘못된 요청": "400 Bad Request", "401 권한 없음": "401 Unauthorized", "403 거부됨": "403 Forbidden", diff --git a/public/locales/ko/translation.json b/public/locales/ko/translation.json index 940eaf84..2413d96e 100644 --- a/public/locales/ko/translation.json +++ b/public/locales/ko/translation.json @@ -56,7 +56,7 @@ "이전 차례": "이전 차례", "다음 차례": "다음 차례", "토론 종료": "토론 종료", - "알림 개수_one": "알림 {{displayCount}}개", + "알림 개수_one": "알림 {{displayCount}}개", "알림 개수_other": "알림 {{displayCount}}개", "{{team}} 팀": "{{team}} 팀", "데이터를 불러오고 있습니다...": "데이터를 불러오고 있습니다...", @@ -241,6 +241,8 @@ "음소거": "음소거", "음소거 해제": "음소거 해제", "발언자는 최대 {{MAX_SPEAKER_LEN}}자까지 입력할 수 있습니다.": "발언자는 최대 {{MAX_SPEAKER_LEN}}자까지 입력할 수 있습니다.", + "템플릿을 불러오는 중입니다...": "템플릿을 불러오는 중입니다...", + "템플릿을 불러오지 못했습니다. 잠시 후 다시 시도해주세요.": "템플릿을 불러오지 못했습니다. 잠시 후 다시 시도해주세요.", "400 잘못된 요청": "400 잘못된 요청", "401 권한 없음": "401 권한 없음", "403 거부됨": "403 거부됨", diff --git a/src/apis/apis/organization.ts b/src/apis/apis/organization.ts new file mode 100644 index 00000000..dc12cdb9 --- /dev/null +++ b/src/apis/apis/organization.ts @@ -0,0 +1,16 @@ +import { ApiUrl } from '../endpoints'; +import { request } from '../primitives'; +import { GetOrganizationTemplatesResponseType } from '../responses/organization'; + +// GET /api/organizations/templates +export async function getOrganizationTemplates(): Promise { + const requestUrl: string = ApiUrl.organization + '/templates'; + const response = await request( + 'GET', + requestUrl, + null, + null, + ); + + return response.data; +} diff --git a/src/apis/endpoints.ts b/src/apis/endpoints.ts index 7589d94c..5469c3d1 100644 --- a/src/apis/endpoints.ts +++ b/src/apis/endpoints.ts @@ -11,4 +11,5 @@ export const ApiUrl = { parliamentary: makeUrl('/table/parliamentary'), customize: makeUrl('/table/customize'), poll: makeUrl('/polls'), + organization: makeUrl('/organizations'), }; diff --git a/src/apis/responses/organization.ts b/src/apis/responses/organization.ts new file mode 100644 index 00000000..afb22afb --- /dev/null +++ b/src/apis/responses/organization.ts @@ -0,0 +1,5 @@ +import { Organization } from '../../type/type'; + +export interface GetOrganizationTemplatesResponseType { + organizations: Organization[]; +} diff --git a/src/assets/template_logo/han_alm.png b/src/assets/template_logo/han_alm.png deleted file mode 100644 index 1167f15d..00000000 Binary files a/src/assets/template_logo/han_alm.png and /dev/null differ diff --git a/src/assets/template_logo/hantomak.png b/src/assets/template_logo/hantomak.png deleted file mode 100644 index 9e4faee5..00000000 Binary files a/src/assets/template_logo/hantomak.png and /dev/null differ diff --git a/src/assets/template_logo/igam.png b/src/assets/template_logo/igam.png deleted file mode 100644 index 65f8a591..00000000 Binary files a/src/assets/template_logo/igam.png and /dev/null differ diff --git a/src/assets/template_logo/jungseonto.png b/src/assets/template_logo/jungseonto.png deleted file mode 100644 index a16e8e8a..00000000 Binary files a/src/assets/template_logo/jungseonto.png and /dev/null differ diff --git a/src/assets/template_logo/kogito.png b/src/assets/template_logo/kogito.png deleted file mode 100644 index 36292c6c..00000000 Binary files a/src/assets/template_logo/kogito.png and /dev/null differ diff --git a/src/assets/template_logo/kondae_time.png b/src/assets/template_logo/kondae_time.png deleted file mode 100644 index f75c2b84..00000000 Binary files a/src/assets/template_logo/kondae_time.png and /dev/null differ diff --git a/src/assets/template_logo/mcu.png b/src/assets/template_logo/mcu.png deleted file mode 100644 index 9ac43528..00000000 Binary files a/src/assets/template_logo/mcu.png and /dev/null differ diff --git a/src/assets/template_logo/nogotte.png b/src/assets/template_logo/nogotte.png deleted file mode 100644 index 56ac3066..00000000 Binary files a/src/assets/template_logo/nogotte.png and /dev/null differ diff --git a/src/assets/template_logo/osansi.png b/src/assets/template_logo/osansi.png deleted file mode 100644 index 5eba3fbb..00000000 Binary files a/src/assets/template_logo/osansi.png and /dev/null differ diff --git a/src/assets/template_logo/seobangjeongto.png b/src/assets/template_logo/seobangjeongto.png deleted file mode 100644 index 95c4daed..00000000 Binary files a/src/assets/template_logo/seobangjeongto.png and /dev/null differ diff --git a/src/assets/template_logo/todallae.png b/src/assets/template_logo/todallae.png deleted file mode 100644 index 45250602..00000000 Binary files a/src/assets/template_logo/todallae.png and /dev/null differ diff --git a/src/assets/template_logo/visual.png b/src/assets/template_logo/visual.png deleted file mode 100644 index 1a74153f..00000000 Binary files a/src/assets/template_logo/visual.png and /dev/null differ diff --git a/src/assets/template_logo/yuppm_law_track.png b/src/assets/template_logo/yuppm_law_track.png deleted file mode 100644 index ab1558a4..00000000 Binary files a/src/assets/template_logo/yuppm_law_track.png and /dev/null differ diff --git a/src/components/ShareModal/ShareModal.stories.tsx b/src/components/ShareModal/ShareModal.stories.tsx index 62b0871c..565f2e00 100644 --- a/src/components/ShareModal/ShareModal.stories.tsx +++ b/src/components/ShareModal/ShareModal.stories.tsx @@ -1,6 +1,6 @@ import { Meta, StoryObj } from '@storybook/react'; import ShareModal from './ShareModal'; -import { createTableShareUrl } from '../../util/arrayEncoding'; +import { createTableShareUrlFromTable } from '../../util/arrayEncoding'; const meta: Meta = { title: 'components/ShareModal', @@ -12,7 +12,7 @@ export default meta; type Story = StoryObj; -const shareUrl = createTableShareUrl('https://localhost:6006', { +const shareUrl = createTableShareUrlFromTable('https://localhost:6006', { info: { agenda: '토론 주제', prosTeamName: '짜장', diff --git a/src/constants/debate_template.ts b/src/constants/debate_template.ts deleted file mode 100644 index 961c0bce..00000000 --- a/src/constants/debate_template.ts +++ /dev/null @@ -1,307 +0,0 @@ -import government from '../assets/template_logo/government.png'; -import igam from '../assets/template_logo/igam.png'; -import kondae_time from '../assets/template_logo/kondae_time.png'; -import han_alm from '../assets/template_logo/han_alm.png'; -import todallae from '../assets/template_logo/todallae.png'; -import jungseonto from '../assets/template_logo/jungseonto.png'; -import visual from '../assets/template_logo/visual.png'; -import hantomak from '../assets/template_logo/hantomak.png'; -import seobangjeongto from '../assets/template_logo/seobangjeongto.png'; -import osansi from '../assets/template_logo/osansi.png'; -import nogotte from '../assets/template_logo/nogotte.png'; -import kogito from '../assets/template_logo/kogito.png'; -import mcu from '../assets/template_logo/mcu.png'; -import ylt from '../assets/template_logo/yuppm_law_track.png'; -import { DebateTemplate } from '../type/type'; -function createTableShareUrl(encodeData: string): string { - const baseUrl = import.meta.env.VITE_SHARE_BASE_URL || window.location.origin; - const normalizedBaseUrl = baseUrl.replace(/\/+$/, ''); - const basePath = import.meta.env.VITE_BASE_PATH; - const pathPrefix = basePath && basePath !== '/' ? basePath : ''; - return `${normalizedBaseUrl}${pathPrefix}/share?data=${encodeData}`; -} -interface DebateTemplateList { - ONE: DebateTemplate[]; - TWO: DebateTemplate[]; - THREE: DebateTemplate[]; -} -export const DEBATE_TEMPLATE: DebateTemplateList = { - ONE: [ - { - title: '산업통상자원부', - subtitle: '', - logoSrc: government, - actions: [ - { - label: '3vs3 통상토론대회 형식', - href: createTableShareUrl( - 'eJyrVspMUbIytjDXUcrMS8tXsqpWykvMTVWyUjJWKCtWMFZ427b1TXPj27YFrxcueN3T8HZWj8LbGVPfdM9V0lEqqSwAqXQODQ7x9%2FWMcgUKJaan5qUkAgWB7IKi%2FOKQ1MRcP4iBbzasedOyESienJ%2BHLP56wwygwUDx8sSivMy8dKfUnBwlq7TEnOJUHaW0zLzM4gwkoVqgtYlJOUCN0dVKxSWJeckgMwKC%2FIOBJhQXpKYmZ4RAnPVmXivQzUDRpPwKqJCff5Cvow%2FI5Zkgqw2NDICyYLPzSnNyIMIBqUUgx6EJBRekJmYDHQcTLgbxU4sg3FodJKc4%2B%2FsNFqf4uYaGBIEtQXPNhDdzFkCiFMVNIZ6%2BrvFOjsGuLnB3QazA6TBzkLMx3AX2DIkhtHXOm0WtCq83zHkzbQfdAwpr8qG7i2JrAbdLRw0%3D', - ), - }, - ], - }, - { - title: '건대타임', - subtitle: '건국대', - logoSrc: kondae_time, - actions: [ - { - label: '타임식 토론', - href: createTableShareUrl( - 'eJzVk09PwjAYh7%2BKec87DPRgdhOciYlsZIyLhpgyOlgc3bI%2FUbMsIXF60Q%2FABTLuHiDxU0n5Dr5lSIwh4m16a5%2B3%2FfV5mzYBpwfKkXwogcNsD5QEGBlSUOB98bZ8Ga0eRnya8efJweopX85ykCC690W93m6ZeuP8UkVE%2BpT1CEIc%2B4EXmpQMtSKGz195tkBueewrX87HGI%2F8lgTMYf0adV1QbOKGVALbYU44KFAUxDTFU0nXxX1XCYQRYZaI0NS2aZxcYEboU2oNzEKsEOV5JpT5ZIz1rne3KWq60VhviRyhUTmWsbo%2BB5M3ndXUM91Qr1XtdLtOFv4xi0Cppp0CNmkg2gGFxa67RS2fkhts5xOHYk6DYppKv7X%2FyblakUuTbhp667sxnz7uMa5USxOu69r%2FEt51w%2BKv7BEu7x3vuuE%2FJ9xJPwDCra7l', - ), - }, - ], - }, - { - title: '한앎', - subtitle: '연합동아리', - logoSrc: han_alm, - actions: [ - { - label: 'CEDA 토론', - href: createTableShareUrl( - 'eJyrVspMUbIytjTUUcrMS8tXsqpWykvMTVWyUno7dc6bqX1vuucqOLu6OCq8bVvweuECJR2lksoCkLRzaHCIv69nlCtQKDE9NS8lESgIZBcU5ReHpCbm%2BkFMebNhzZuWjUDx5Pw8ZPHXG2a87mkAipcnFuVl5qU7pebkKFmlJeYUp%2BoopWXmZRZnIAnVAq1NTMoBaoyuViouScxLBpkREOQfDDShuCA1NTkjBOKsN%2FNaIc5Myq%2BACvn5B%2Fk6%2BoBcngmy2tDUACgLNjuvNCcHIhyQWgRyHJpQcEFqYjbQcTDhYhA%2FtQhopuHrTR1KtTpIjnH298NwzKutE95sWPFm4YY3TWvwOsmICk4yIspJAxY%2B2CKLruFDnJPoFD7ERdYAh88Aph%2FM8Bnw9ENclIHKNfzhY2RIt8Q8YI4ZwJAhLuXQ1TGxtQBiH58N', - ), - }, - ], - }, - { - title: '토달래', - subtitle: '성신여대', - logoSrc: todallae, - actions: [ - { - label: 'CEDA 토론', - href: createTableShareUrl( - 'eJzdkz9PwkAUwL9Kc3MH1Ei0G386kEhLaFk0xhxwQGO5Ni1GDSFxIIYEB1wMA5CyiEOHM9GEz8Sd38E7qogGGYW43fu9u%2Fd%2BebnXBFYZKHsH%2BzKwcMUBShNgWEdAAW%2B3Ae2GdNRn3aGUUtMJSZBxAGTQuHbFjVTBMPVs5ljlCFYRLkMO%2Bdn1HN9EsK5FhRgJWfuZ85KDlzklfXp3w%2Fkl9LCFq0lk20CpQNtHMqhY2PJrS6jF28KizR%2BeNIHfgLgkauTyusEr%2BC5CpZoZac2mhI0JJQP2MOW5onP1kdD0fDZxJPwtIXAY48l5A3xh2xHNIU8Y%2FkCGi%2BA5N%2FzEvoiRF4UtecknpWtb5bNyPq89Rp7YpMOG%2FXU%2BO7t%2FNaBNCmlqwczPm3xzYqN7FrQl1h3MSHudVPwvnXpsECy28EvJzGTVs2TCUNMLrajFr2LxWOyfzGrVh6KTDg1f6GMobc%2FWbcLptPUOQLEj%2Bg%3D%3D', - ), - }, - ], - }, - { - title: '연세행정법학회', - logoSrc: ylt, - actions: [ - { - label: 'CEDA 토론', - href: createTableShareUrl( - 'eJzNlD1rwkAYx79KuKFTCirSlmy%2BZBBqIiYuLaWcempovITE0hYRSrHFgkMW%2B0YpcaqDQyoU%2FEzm8h16MdaKtih0iFvud5fn%2BfG%2Fh2sCpQy4%2BH6UBQquaIBrAgzrCHCAPDqkPfYe7ondc0c9r%2FfsvXSZXSbFpxOMd2e7fRuwoHGl%2B4dTBUkWs5kjniJYRbgMKaTfuqGZMoJ1YVbTGZL2B%2BUlDS9y13lyu9eUX0ADK7iaRKoKuApUTcSCioIVs7aAWrQtLKr0x%2BMmMBsQl%2Fwaubwo0QqmjlCpJgda5O020CxqlzMkiPls4tA3V%2FzWsXiE7k5r43NVDXAOGb7cEpJ0BM%2Bo3Dc2%2FTUyaM2oO%2BqAFrsgkxKFFZnJp0WcAUP6DrkZbolTaAH9dlthBxTiBMW2cII2cwotoPAnaNVJ4AtyftpmKSOLvNrzN%2FPHSs5k%2BdNkQuLTc7OgyZ9qe5HIejN%2FuYmX1x24bYu8d9zhmNlhJiNnzVVGD%2F4f21TupPUFcJhU9g%3D%3D', - ), - }, - ], - }, - ], - TWO: [ - { - title: '중앙선거방송토론위원회', - subtitle: '', - logoSrc: jungseonto, - actions: [ - { - label: '열린 토론대회 예선, 본선', - href: createTableShareUrl( - 'eJzVk09LG0EYxr%2FKMudQtoYeujejKwjNriTrRREZ40SXrpOwm1BLCOSwSiQB9WATykZTWvSS0i1N2xxy6sfZefMd%2Bo6j1iB4KAp6GuaZ98%2FvmXemRtxNYqT1dIq4vFgiRo1wusOIQUS7MTmJxLdx8vOrBp2hOI8n%2B33xqS8PPrY16DYh7P%2F5LX6McCUpUnlflnlzy3nHzi6umCjRLcY3KYpYAytBJ05GTQ16XTEYJnEDTvegF2qTwyO4wGZd6AzgZKzJtq0vLzC%2F7JcCh9EdSyFBPIDwO%2BqFEr%2Bti7iLUKi%2Foz53%2BVaGeR4xitQLWIoUXe4G20qq%2BFVWR1K64WHeao0EFcoLssRSzs5jgaDMWGHbUU5Uu0m7oUErgtNjEUfwYYRRG6XdqxDLzmVn30jzriR5rePhZSesfXUfGXPBzpnrpjV%2FE6ZLB1VeIcZMfU2JS8yXhojBq553I%2BXLjL5FQ9dyIPfMV9t66hb%2FnG3d4VfX8jz4LXPZyV2STI%2Fg81gchsmvtqbe3hS8s5g11zOzefMfmWqjLEyRKLi0rj8gWytK4hCGPXF2AP3oUdBevtL%2Ff%2Brioon%2FTJwPtKc8%2Bft%2F3tP1sFb%2FC67gA%2Bk%3D', - ), - }, - { - label: '열린 토론대회 결승', - href: createTableShareUrl( - 'eJzdk09LAkEYxr%2FKMmcJ%2B3fZW9YGQe6GbpciYrWxlrZRdpUKETxYVArVoZRYzSjqYrSFRYGfaGf8Dr3TmGZFFHTyOM%2B%2Bz%2Fv%2BnndnsshcQXIwgEySSCI5i4ixgZGMaCnfPnHpXct%2FvJVYuUmvPam9W6cXdf7lrCT5Dx47eEEBlN5OccPkfFTXwjMLCkjGKiYrBohghhas7PnPexKrVmij6Xt5Vtth1YLUPjxiNzClwsoNdtKS%2BLzi1RD4U3bS0bGxoQoW5jVY4R70eJJ81KlXARjQNw2bmGQ1hC0LyWk7gwMoYRLTWespOQA1YhbYFrPISRskzjvMRbQo%2BJ0UxvE1XQQR09qlvMSKLqsdS9Rz2ekzlMWSW50aVYuEJ2Z5eJOTDI%2FAAmNvs6B7ZyEhZVqLKMuKOtWtGw3yDBmSBksu8FNlr3AktyTEOWzz7EgmGcvqStEUNtYh%2B7vs8DO2xZHP6Gad1NQvWcUGBy%2BrqszrkTfo%2Fl972aKHBf%2Bp1LnKfTn1mbCyHJqIKj0yMUaE7SMRcGN8Ff%2FGVnR9r8CaVXq%2Bz%2Bru79B%2BgTM8HvxE8zHRH24IvdmD50uvG4NySb57%2FAMWdyn3Ckv7L8s%3D', - ), - }, - ], - }, - { - title: '통일부', - subtitle: '', - logoSrc: government, - actions: [ - { - label: '통일토론대회 형식 (예선)', - href: createTableShareUrl( - 'eJyrVspMUbIytjTSUcrMS8tXsqpWykvMTVWyUnrbtvXN3D0Kb9sWvF644HVPw9tZPRpvZnS8aVmgqaSjVFJZAFLkHBoc4u%2FrGeUKFEpMT81LSQQKAtkFRfnFIamJuX4Qs95sWPOmZSNQPDk%2FD1n89YYZQJOB4uWJRXmZeelOqTk5SlZpiTnFqTpKaZl5mcUZSEK1QGsTk3KAGqOrlYpLEvOSQWYEBPkHA00oLkhNTc4IgTjrzbxWoKOBokn5FVAhP%2F8gX0cfkMszQVYbWhgAZcFm55Xm5ECEA1KLQI5DEwouSE3MBjoOJlwM4qcWAc00fL2pQ6lWB8kxzv5%2Bg8cxfq6hIUFga9DcM%2FHNghaFN91zXm1owecsM8pdBeISDCBQKiAQQEZUCCAjjADClnQGzDGDMbZwuOnV1glvNqx4s7zjzdwZKE4K8fR1jXdyDHZ1gTsLYgVOh4GT%2FnB316DLcW%2B2znmzqFXh9YY5b6btoHlaNyYq4w2Em2JrAWSqgfQ%3D', - ), - }, - { - label: '통일토론대회 형식 (준결승, 결승)', - href: createTableShareUrl( - 'eJztlNFLwkAcx%2F%2BVcU8Fe0iNKN%2FU9iCkEzdfiohTTx3Nc2xGhQg%2BTJH0wR4KKQ2LoB56WIJQ0F%2Fkbv9DN1dhlhaY6ENP233G%2Fb6f%2B93tCkBKAq9nw8MCCadywFsAGGYR8AKr0iPtF8aqdMzrjlkvWRd1xmqekVp7idyW%2Bl2DnDyzjPNcBizIHyv2tEBMEPlQcJujCKYRTkIK6bui5jQRwWzYqU6MB6I%2FUp7I4WFuGk2aRfkhVLGE034ky8CbgrKGWJCSsKRlhlCRxsK4TCfuFICWhzhh14hEeYFW0BSEEhnR0SJXZboMSuO5ozcU5qMh35ZtLtnR7tUV%2BnVQGx%2FIsoMjSLXlRpCgILhP5d6xZo%2BRSmu6zG4VFNkhmQAfXhyZMBcTo4OYEZ9T0tEZUmv1DX2S1tr0VvbwxwbZp2Byg1zrf9Ag95cGfXd05iYz7W653DPYrnFSHZ1cNph%2Br0GMe3JXJe3mJzUxGOL2%2FD6B2%2FzQc5LG%2Bg2a%2Bq%2B3EHqLdj%2BQXovclBnTaJHzp1n%2FAsDzq2tiHk67xVcoYtDy', - ), - }, - ], - }, - { - title: '비주얼', - subtitle: '명지대', - logoSrc: visual, - actions: [ - { - label: '2:2 자유토론', - href: createTableShareUrl( - 'eJzVkk9PwjAYh78K6XmHOQ0xvQHWhEQ2so2LhpACBRZHt2wjasgSD%2BBFD56Ih0lQrx7wYKIJ32j1O9hS5I%2Fh4g1vfZ%2B2v%2Fd5m%2FaB0wRw%2F%2FBAAQ5teQD2AcVdAiBIPwfsZcZGM3b7mNGglmHje5ZMvm4m6dMEKCC68sWxQsWyjVLxFHGE24Q2MYd87QdeaBPc1WUam76ywRvnDY%2Bu83T6kN5dc36BA%2BrQdp64LoAt7IZEAS2HOmFHoijokZh3xXWX3zvrgzDCtCEiyqZh8YDQJ6TRsaUVGw%2BlZd27XCDdMEu5EyHuiM5ZlW%2FOk3nWYpY8OjZMVEP60fKYKox7NAJQi6sSlkkgBgCQ9lx3iSyf4HM%2BwA8ORU0CWcbKmm%2FB0P%2BVr44qtjk3%2BaW88R1W4naxhGr5nIVWVrKF1N%2BwkGJZVd3itaepf37G94Q9DzPpNGGjj918za2%2FdTe1q%2FE3Vb9xjg%3D%3D', - ), - }, - { - label: '2:2 CEDA 토론', - href: createTableShareUrl( - 'eJztlTFPwkAUgP9KczMDNMRoN8AzIZGWQFk0hBxwQGM5mhaihpA4gDHBARfCUAzqoINDHUg04RfR8z945RBQCIsxonHrfb2%2B973r62sdaHkgBf2iD2ikUAFSHRBUxkAC7kuT3o1od0TbfUGURCECd0PC6%2FnAvRkAH6ieGt6uSCqpKrHoAWQIFTHJIwbZtWFWLBWjssyDUeeRNp8Yz1XIInednnt5xvgxMolGimGs60AqIN3CPlDQiGaVOKqaNdxgWVFWZ88d1oFVRSTnhYgnlCQLYBkY50oqt6LXLW6ZrZxMkawkYqF9T1zzMu%2F42c1JZBZrWksY7ikJmIHy7myb3zOukSqQxEaawzg2vQKARGq6PkNJA6MjVsA7trw1Nvmy4VvwlWFKTUxMPilf0UFToG177DTXmW%2F9mHlEkZdOejzsUOdBoPcXtN9bpx3Y3ijv%2Fw75DvNV3%2BJv6JCvnnhA3Dz1DrUHs2k9N1ejMZgJh5JwbsVTcP0PFlws6L2XJa9JyX%2Bxh1dOi6FNb1uC69i0%2B7yZQ2Plb3AztdONN32z7RU%3D', - ), - }, - ], - }, - { - title: '이감', - subtitle: '경희대', - logoSrc: igam, - actions: [ - { - label: '하이브리드 토론', - href: createTableShareUrl( - 'eJzFkk1LAkEYx7%2BKzHkPvkDI3tT2ILS74q6XImLUUZfW2WXXqBAhIiPIgxCGhzW0Q3TwsEWCn8kZv0MzrpnYix4Kb%2Fv8Zvb%2F%2FHieqQOjCMRYPCYAA5csINYBhlUEREB7bxO%2FTW97oWmnywoybpGnIbnzQtPrPhn0gQBq5za%2Fmcppuiqn9yWGYBnhImSQfduO5eoIVpV5oD%2BkVy%2BMFyy8zInfJa0Lxk%2Bhgw1cTiLTBGIJmi4SQMnAhltZQg3WFuZN9uNBHbg1iAs8I5NVNZbg2ggVKnqgRR%2BagWbeOpsjRc3KiT1ubvDWkXiYnc6y8YlpBjiDHC63gjQbwWMm94FdXiOHZUbI6w1oCEsyKVX5IjMZtan%2FTAc%2BvRz%2BqhT9A6XoRkpbm893y9ryfBQpp2dnbVZG1KZef%2FHeP630tCwdJROatLswC5r8qLYTDq834%2BX6vY08%2BtgMEd%2Bj9%2BN%2Fn1Vso%2FVtw%2Bmw8Q6hkrn4', - ), - }, - { - label: '2:2 자유 토론', - href: createTableShareUrl( - 'eJyrVspMUbIyMTTQUcrMS8tXsqpWykvMTVWyUnozd8urDRPedM9VMLIyUngzb8KbOQveti14vXCBko5SSWUBSI1zaHCIv69nlCtQKDE9NS8lESgIZBcU5ReHpCbm%2BkGN2rDmTctGoHhyfh6y%2BOsNM173NADFyxOL8jLz0p1Sc3KUrNISc4pTdZTSMvMyizOQhGqB1iYm5QA1RlcrFZck5iWDzAgI8g8GmlBckJqanBECcdabea0QZyblV0CF%2FPyDfB19QC7PBFltCfRvEtjovNKcHIhoQGoRyG1oQsEFqYnZQLfBhItB%2FNQiCLdWB8klzv5%2Bg8Qlfq6hIUFgO9AcgxKHCCeFePq6xjs5Bru6wJ0FsQKnw8yNDLC4yxAkSmIAbZ3zZlGrwusNc95M20HvcMKadujtoNhaAMq8Q9Q%3D', - ), - }, - ], - }, - { - title: '한토막', - subtitle: '한양대', - logoSrc: hantomak, - actions: [ - { - label: '반토막 토론', - href: createTableShareUrl( - 'eJyrVspMUbIyMTTQUcrMS8tXsqpWykvMTVWyUnozd8urDRPedM9VMLIyUngzb8KbOQveti14vXCBko5SSWUBSI1zaHCIv69nlCtQKDE9NS8lESgIZBcU5ReHpCbm%2BkGN2rDmTctGoHhyfh6y%2BOsNM173NADFyxOL8jLz0p1Sc3KUrNISc4pTdZTSMvMyizOQhGqB1iYm5QA1RlcrFZck5iWDzAgI8g8GmlBckJqanBECcdabea0QZyblV0CF%2FPyDfB19QC7PBFltCfRvEtjovNKcHIhoQGoRyG1oQsEFqYnZQLfBhItB%2FNQiCLdWB8klzv5%2Bg8Qlfq6hIUFgO9AcgxKHCCeFePq6xjs5Bru6wJ0FsQKnw8yNDLC4yxAkSmIAbZ3zZlGrwusNc95M20HvcMKadujtoNhaAMq8Q9Q%3D', - ), - }, - { - label: 'CEDA 토론', - href: createTableShareUrl( - 'eJzVlc1Kw0AUhV%2Bl3HUWbRXU7PoTQbBJaetGKTJtp20wnYQkRaUERFQUXbgRXKi0K110EQVfykzfwTumlkKlZCXTXeZk5sx3DydkAGYL1LWtDQVM1rZBHQAjPQoqTB6eJlfD6PWG3z6nCloxlxLL0RAU8E8dsaOwV60ZpZ19DSXSoaxFUMRnx7W9GiU9PTbi4ZhfvKPetNm8HoWP0d0Z6sfEZSbr5KllgdomlkcVaJvM9Lqx5Lt9GuCtpGHhuYMBeD5hTWFRrhhVNPAcSpvdWkzFXy5jyoZ9MpV0o1LK7QpwU9ycXU%2Fj2x9rNJsOk9e2jYp2qOnF2b60QO4zH08E9VgsU1dMACrrW9ZMqjqUHOEEv7In1tRF10z0cQ2BModcMPQF5K%2FPex6%2B8VHIz8fLwDOb%2FwaeTQQuedZ%2F1UPCrJOBS5V1snqsRNbS93ox6xXpdbKSiN%2FA8qyl%2BxQlR5Y%2B5WSNlhC5HnwD9JgkZg%3D%3D', - ), - }, - ], - }, - { - title: '서방정토', - subtitle: '서강대', - logoSrc: seobangjeongto, - actions: [ - { - label: 'CEDA 토론', - href: createTableShareUrl( - 'eJzVlU1LwzAcxr9KybmHvVxcb3upILh2dN1FGZJt2Vbs0tJuqIyCSCfCPOhB8TBl86SwQxUGfqY1fgeTbY7hhBUPkt2Sp%2BmT3%2F%2FhKe0CowakZColAgPXLSB1AYYtBCRA%2FEEYvJLh3eflkPQfhaycSwt0HY6GQATtM5sdypaKuprfO5CpBBsI1yAV6dp2LFdHsKUsvIIx8d%2BoXrXwqh4GD%2BH1OdVPoIMN3Mgg0wRSHZouEkHdwIbbnEttp4M8eiusmPS9wy5w2xBXmUVBU4vUwLURqjb1ORV56s0pK9bpQlJULZ%2FeZ%2BAGuzmeiNGnM2tqthgmI%2B%2BqmnwkK7nluRhD7uA2kBJeeS4WkMMmABLumOZSKtoIHtMJvmWX7ZFDXePh%2BxXwxBXkrKqsIU8nNyR4EcgoIBdjTsgTkcg5D%2Fu3fvAYdjRyrsKO1o%2FtCJv7Zq%2BHvS3NXidX5JKuzWB%2B5H1Lhr5A%2BoNp4PMBz7Ybe8L%2BYht6svNvaScj9YRz5D%2BmzNvXuIXIZDIgzz0hDAbk%2FoMT8mj94Je87H0B1zvnzQ%3D%3D', - ), - }, - { - label: '국회의장배 토론', - href: createTableShareUrl( - 'eJzdk0FLAkEUx7%2BKzNnDah5qb2obCLkr7nopJEYddWmdXXZXKkSIsAj0YIdAQmU9BAUGk%2BCXcsfv0KxrainhKazb7o%2BZ%2F%2Fu94b0aUAuAj3BcEKi4qAO%2BBjCsIMAD2ui65JU6j9M7hzZ7gcn4bfrUor0O7T%2B7hAQYdgcOCAL7yvDOxzOyIiUTJwJDsIRwATLIvg1TtxQEK%2BI8lgxp453xvI5XuUs6buua8QtoYhWXYkjTAF%2BEmoWCoKhi1Sr7yDarqM6qwpzG7p3WgGVDnPciUmlJZgGWgVC%2BrPhWtH%2FrW%2Bb0yzkSpXQyeuyJq17lUJj1nptFs7B5MzHhSEoLZ4J4uDjHecpVbAM%2BXM%2F6MIVMrwPA46qmLZBsIHjOOvjElvePTJYackf3oB5cUY5L4n9QnozblLwE6IDQm%2BGOmIfXzDfNx98wF4WMkp7JfJuUNu06i0VcuiuJpHAWi8rC0ssv4jfwxcNXi%2BxzG8xmTS%2FEvGvbaT1QpxGgze6ENH5604PfetI1842jMCK7s3d72%2B3d7iln6x%2Fd%2BDWm', - ), - }, - ], - }, - { - title: '목포가톨릭대', - subtitle: '', - logoSrc: mcu, - actions: [ - { - label: 'A형 토론(20분)', - href: createTableShareUrl( - 'eJyrVspMUbIy0FHKzEvLV7KqVspLzE1VslJ6vWrl2%2F41rzY0vG1b8XrZ2tc9DQq6Co5vZ0xVeNu24PXCBRpGBq%2B3tWgq6SglpqfmpSQCtQDZBUX5xSGpibl%2BEEPebFjzpmUjUDw5Pw9Z%2FPWGGUADlWp1lEoSk3KAItHVSsUliXnJIMmAIP9goJbigtTU5IyQygKwQfNagXYCRZPyK6BCfv5Bvo4%2BQKGSTJCZlkAvJKXm5ChZ5ZXm5EBEA1KLQJaiCQUXpCZmZ%2Balw4SLQfzUIpAHanWQ3OHs7zco3OHnGhoSBLYB1Skb1ugDw1HhzbwJb%2BYsgEQKisNCPH1d450cg11d4I6DWITTeSZGBlhcZ2aA5DaQLsKhtHXOm0WtCq83zHkzbQd9Awtr4qGvc2JrAbVgNdA%3D', - ), - }, - { - label: 'B형 토론(25분)', - href: createTableShareUrl( - 'eJyrVspMUbIy0FHKzEvLV7KqVspLzE1VslJ6vWrl2%2F41rzY0vG1b8XrZ2tc9DQq6Ck5vZ0xVeNu24PXCBRpGpq%2B3tWgq6SglpqfmpSQCtQDZBUX5xSGpibl%2BEEPebFjzpmUjUDw5Pw9Z%2FPWGGUADlWp1lEoSk3KAItHVSsUliXnJIMmAIP9goJbigtTU5IyQygKwQfNagXYCRZPyK6BCfv5Bvo4%2BQKGSTJCZlkAvJKXm5ChZ5ZXm5EBEA1KLQJaiCQUXpCZmZ%2Balw4SLQfzUIpAHanWQ3OHs7zco3OHnGhoSBLYBzSkT3sxZAIkMFAeFePq6xjs5Bru6wB0FsQCns0zNDbC4yswAyU0gXYRDZ%2BucN4taFV5vmPNm2g76BhLWRENf58TWAgArWzES', - ), - }, - ], - }, - ], - THREE: [ - { - title: '오산시', - subtitle: '', - logoSrc: osansi, - actions: [ - { - label: '초등부', - href: createTableShareUrl( - 'eJztVsFKw0AQ%2FZWw5xTaKKXk1moEwSYlTS%2BKyFq3bTDdlqSiUgoiRQQ9KIJ4EKkgeLCHtIj0m9z1H9xtYkwxVPRgKeaWvLzMzL7HzGwbmDtAljKSCExcaQC5DTCsIyADevNAj116diu8nfTIfU9ICPT5lFwNyMsREEHrsMlZS6WioeVX1xUGwSrCO5CB7LlpNxwDwbrqB3P7tDtgeLmBwzhxb8g5D7cPbWziag5ZFpAr0HKQCComNp1aCOqwtHDbYj9utIHTgrjMYxR0rcgiOE2EyjXDK4sOn8jwlD6OBC%2BzQNxbej1itO3Ggc9RNT2fXeNHMXkt0mKSfR0nY9H942VXDEXfKhpZ3QiIC0l%2BjD3cAnKqIwbUnLKi6cqWoi7%2FgvlJlEJEL3uYlwiFXOhsenAB2VxSIOM9ywqgYhPBXSbpB%2Bzwd2Rze3iKQD5VKRn6WIdJBe8uaa8rMP9f3e403dKBbBPpf1IRf52oaUlTv7eUnvVJf6qlqUyEpRHqp3%2Fl0z9V32vZuKHmytLpM9K3NG6oP1SfXF7EG2p%2BLY2akV8sjRtqJurHG2oOLZ0%2BI%2BMNNYP7QXcUb6j5tTTyFh9YGs%2FICEs3O%2B8MouWw', - ), - }, - { - label: '중등부', - href: createTableShareUrl( - 'eJztVkFrwjAY%2FSsl5wp1goze3FZPWyu1Ow0ZVTNXVttiK2xIQUYZA3eYDIYHGQ6EHeahehj%2BpiX7D2utdhVLxzxMCrklX1%2B%2BJO%2F1fV86QKkDlqGBol3ogO0ATW5CwAI8GONbF%2FeG1NfdCL2OqAyFx330NEUfXUADuQG1uuzhvLHR0k0Jyk1%2BudKdYGfqxWu6Fo0jd4AeusCmgSVXVS9y1gGmJWs1%2F2NJFMreEtOAsHYp3RiLRLN3NLvHb3MqSEkhd4if5x6sql8vMbwgnhSOvZCl%2BJvkGCYYlmDL3xqwWltVw1DZgPKVojVWYdOfw1ZwjSpU1cWhrCB1oShx4nlZKohSJL9%2FrbZmATZr0yH0gCsKInfO8UdbIH%2BAexFgsHsUl4mkzNkVHxvSx3OnkrjgYZ3Blz4eOZSn4qfrJPGWZ1b3X%2BPrLxT607UzHQr875Li3gRNEiXN7jOb2sTQmN%2BK8MqWv0vK2Q%2B8SAyVKkMl18ilpMRQ%2F8g%2B6j%2BSDpVeQ8XVyA1JiaF2wj7pUCk0VHKNJB1qB%2B8DZ046VHoNFfuKDyUlNTJG0or9DTqI0dk%3D', - ), - }, - { - label: '고등부', - href: createTableShareUrl( - 'eJztVlFLwlAY%2FSvjPk%2BYCRJ7s5pPtclcTyEy9WajuQ03oZCBxIjAHpIgfJBYEPSQD9Mg%2FE3e9R%2B6czYnjkU%2BJIO93fvt3O%2Fee87O990ukBqApkggKecqoLtAEVsQ0MAdvro3jtsfEV%2B3NnqxiQwx%2F7DR4wR99gAJxCZUGiLG4bHWVnUBii12udIZu9YEx%2BuqEo4jZ4jue8AkgSHWZBw56wLdEJW697HEc2W8RNcgrF8I19oi0fQdTe%2FctxnhpySQM3KfZhhWU6%2BWGJbjTwrHOGRI3ia5POUPS7DtbQ1opSPLQaisQfFSUpo%2FYd2bw7Z%2FjRqU5cWhDD91oSgwfLUsFHhhlZ%2FyrtVRDEBnTTKAHjBFjmeqDHu0BXIF3AsB%2Fd3DuEwoZc6seNiAPpY5FfgFD%2BsMPg9c2yKwinPHiuPNo82%2F%2Fxpff6HQm66d6ZBjf5fU7Y%2FROFbS7D61qU0EjfmtCK9s%2BbsknH3fi6mhEmWo%2BBq5lDQ11D%2ByjwYPaYdKrqGiauSGpKmhdsJ%2B2qESaKj4Gpl2qB28D6xZ2qGSa6jIV3wgaVojIyStmN8r8tIZ', - ), - }, - ], - }, - { - title: '노곳떼', - subtitle: '한국외대', - logoSrc: nogotte, - actions: [ - { - label: '자유토론', - href: createTableShareUrl( - 'eJyrVspMUbIytrDQUcrMS8tXsqpWykvMTVWyUnrduuPV5s2vp%2B150z1X4c28CW%2FmLHjbtuD1wgVKOkollQUgJc6hwSH%2Bvp5RrkChxPTUvJREoCCQXVCUXxySmpjrBzHpzYY1b1o2AsWT8%2FOQxV9vmPG6pwEoXp5YlJeZl%2B6UmpOjZJWWmFOcqqOUlpmXWZyBJFQLtDYxKQeoMbpaqbgkMS8ZZEZAkH8w0ITigtTU5IwQiLPezGuFODMpvwIq5Ocf5OvoA3J5JshqMwOgJNjovNKcHIhoQGoRyG1oQsEFqYnZQLfBhItB%2FNQiCLdWB8klzv5%2Bg8Qlfq6hIUFgO9AcgxKHOJ1kaGRAA0dhi6hXmzYMkoiin0tiawFdfDzC', - ), - }, - { - label: 'CEDA 토론', - href: createTableShareUrl( - 'eJzNlTFPwkAYhv9Kc3MHgcRIN0QGE2kJlEXjcMABjeXatBg1hMQBDAkOOkg0Kaa6uDBUiQmDv4g7%2FoN3VA0BJB2QuvXea7%2FvyXvvfW0ArQSk2E5cBBouG0BqAAxrCEiAtEfj4ZD0Pmi3LyRTewlhcuWSJxeIoH5h8jeS%2BZyqpPcPU0yCFYRLkIns2bQMW0WwJvuFqDegrVemFw08qxPvnlxfMv0MWljDlV2k60AqQ91GIihrWLOrM1KTtYUFnX141AB2HeIir5HJKjlWwTYRKlZVH4s%2Btn3MgnH%2BJclKNp044OQabx2JbrHdaW18quu%2BnEEWh5uTciaCJwzuW7b5GlmsZoS8dUBTnIFJKvICzOThjvZH9KVDBqNVSNtrIIoGIgrNnmVnFa49y4h4KjdgT%2BzfpSdYnkOzJ%2Bz0LNojp%2FJqdtpl7n7dUMf9mZW%2FQsXXQMWXwZhuqdsSaNcZe62%2FPrwFqBCvWbCRGBrM0t%2FXu0Of2wLxHNpbmeoNzqEwmI6bn4qAFGY%3D', - ), - }, - { - label: '의회식 토론', - href: createTableShareUrl( - 'eJzN1MFLwlAcB%2FB%2FRd55kFMI201rByGduHkpIp761NF8E2dUiCChEejBoERCRTt18LASw0N%2FkXv%2BD73nKq2sJLK87X3Zfr%2FPfntveaDGgeDecHJAxQkdCHmAYRoBAVjl4ajft%2BqPpNJykFZjfF1lV%2BOzjtXtAA7kTjLsts2IrEgB%2F45II5hEOA5pSK8zWd1QEEwH7WrE7JHSHc1jOp7NLbNhVYs0P4JZrOKkD2kaEBJQMxAHEipWjdRMVKBtYVSjD%2B7mgZGDOMZqhMKSTCsYGYRiKcVmkXbZZkb14%2BcoKIUD3m0mV1lr3kXfOTqpjQ81zY5DKMtw7yI5g%2BABxb3EBlujLK3JW%2FfnoMDNYDal4Opg5k7m4XJkFm0S52DzN6%2BWTnMtNqfVoAXFiBKetHmj4wV%2BuvunJsUfEPd9XlncenXZLT6F8R7n9y62XERF2jXS7PyKy70%2BzzUZ8g9YF6RTcpBKc2SWlv0NP6Dmba7RoEbMW9I1yWnvS5Dnz47iCpLIoEluyvTsNUl9uPyzt%2BZe7MfwL6q9whOwPJLP', - ), - }, - ], - }, - { - title: '코기토', - subtitle: '고려대', - logoSrc: kogito, - actions: [ - { - label: '2:2 일반토론대회 형식', - href: createTableShareUrl( - 'eJzVkj9PwkAYh79KczNDaRi0G2BNSKQlbVk0hBxwQGO5Nm2JGtLEAVwk0cE%2FxKBBTZwcaqKGQb8QLd%2FBO4oI2MVJ2HrP9X7v8755W0CrAD7BJmJAw1UD8C2AYQMBHgSfF6OhNz4ZBKe3DMdzTHD96j9R4N8P%2FO7x%2BKbLjHuX5BbEgHNk0jfpvKJK2cyuQBCsIVyBBJJv0zJsFcGGOI32noP2C%2BFlA89z3%2BuRYMIPoIU1XEshXQd8Feo2ioGqhjW7HiLHaiKXVIUlnbzbawHbgbhMI3KypJAA20SoXFdDq%2BCuQ5QJLRmHUyRKcja5Q8U1WnmTJZeTZJI17SUlbEuyUBTErdlvLDVuYgfwnFsIYQ5ZtAHA46auz5BiIrhPGvjGNj0jKzy6sTnftCSula8o5FV5YrKkfB70B%2BFuLIirmaxQTCUV4ccqLBHqL1iEYgmOjfCKU%2FrHMT5%2B%2BGft0TtZ099eSwONb%2FzbRCM3dj3UI6f%2B1g8eOozv9YOr4WrucOTEV1O74H4BEob9Fw%3D%3D', - ), - }, - { - label: '3:3 통일토론대회 형식', - href: createTableShareUrl( - 'eJztlk9LAkEYxr%2FKMmcPphW1t7QNgtwV%2F1wKiVFHXVpH2VUqRPCgEihUUCGhYXWoQ4eNMDzYF9odv0PvqonE4nmMbjvPzDzze1%2BeHaaC1DQS170bHqTSTAGJFURxniARsa8ba2iOm33W6gl%2B0S%2BMmwPWG4FgP%2Fbtdm183xbGnVuYRR5UOi86e4LxaEwJ7R9KIOEsoWkMInwX9YIRIzgvz6zNN1Z%2FBz1VoIu6bXbAGPRTrFOVZgNE05CYwZpBPCijUtXITaWSXiZVOBUnNdh3VEFGCdOUYxGOKFEwMIqEpHKxKRV7aAAyqMnC2UySlUho58ABV52T13xemJ1Yg9msmIC0p0SkY0nena%2FzOshlWkKir5qYimGiOxUgkZY1bS5FiwSfQAU%2FsuGMiT4dVj0LwEFFXi1gWYrHIhOUX8zXrF8XWKtrmfVl6JtctdoaXDHzlb1csF6H04a7RdpuDeyP2jLgba54V6DNbunguc2r%2Bx%2B6Bhqufm6vPNdo8Az8t7LBnkf2Zd36hPfG5PGxtOlbXKVkRdD%2Fu84N%2BqDLnhqCbXbZ3ZDT28U1LZxyJ6rfo3R1ow%3D%3D', - ), - }, - { - label: '3:3 통상토론대회 형식', - href: createTableShareUrl( - 'eJzVkkFPwjAYhv8K6XkHRKNJb4A1IZGNbOOiIaRAgcXRLduIGrJEo3KRgwdNiFGDdw%2FTxMSLfwi2%2F%2BBXigjqxRve1qfr%2Bz1v0x6yGghvpDcVZPGmg3APcdphCKP4%2FXr8FiX9UXx5n1rH66mk%2FxqfnQKYPI4mg5PkdpBKhjewixQUHLviTL5smFqxsEcA0RbjDQoQvl3P8U1GO%2BosOnqKz5%2BB1x2%2ByCfREIKBH1KPW7yVY7aNcJPaPlNQ0%2BKW35Yo8LoshKm0ZsO5%2FR7yA8rrIqKkawYE%2BC5j9bYpreKHC1AGWnOOZkjV9GJ2V4hbYvJaJg2702gIm5XJkR1NJ1Wibs%2F%2FSwvlLg8QzoQVCUvMEw0Q5l3bniPDZfQAGnxiX6yZJ5ehsiCc19T%2FJaySsqlPVb45X8V3I%2Fk6lszNQpFUc1mDfFnJEVJ%2FyUKKbYlyP7ymlf92j%2BOXaHXv8beXunLClfAD%2BBVxjw%3D%3D', - ), - }, - ], - }, - ], -}; diff --git a/src/hooks/query/useGetOrganizationTemplates.ts b/src/hooks/query/useGetOrganizationTemplates.ts new file mode 100644 index 00000000..523bcbff --- /dev/null +++ b/src/hooks/query/useGetOrganizationTemplates.ts @@ -0,0 +1,12 @@ +import { useQuery } from '@tanstack/react-query'; +import { GetOrganizationTemplatesResponseType } from '../../apis/responses/organization'; +import { getOrganizationTemplates } from '../../apis/apis/organization'; + +export function useGetOrganizationTemplates(enabled?: boolean) { + return useQuery({ + queryKey: ['OrganizationTemplates'], + queryFn: () => getOrganizationTemplates(), + enabled, + throwOnError: false, + }); +} diff --git a/src/hooks/useTableShare.tsx b/src/hooks/useTableShare.tsx index 0fd2b07a..6acc5553 100644 --- a/src/hooks/useTableShare.tsx +++ b/src/hooks/useTableShare.tsx @@ -2,7 +2,7 @@ import { useModal } from './useModal'; import ShareModal from '../components/ShareModal/ShareModal'; import { useGetDebateTableData } from './query/useGetDebateTableData'; import { useEffect, useState } from 'react'; -import { createTableShareUrl } from '../util/arrayEncoding'; +import { createTableShareUrlFromTable } from '../util/arrayEncoding'; export function useTableShare(tableId: number) { const { isOpen, openModal, closeModal, ModalWrapper } = useModal(); @@ -32,7 +32,7 @@ export function useTableShare(tableId: number) { // Process URL when data is successfully fetched useEffect(() => { if (data) { - setShareUrl(createTableShareUrl(baseUrl, data)); + setShareUrl(createTableShareUrlFromTable(baseUrl, data)); } }, [baseUrl, data]); diff --git a/src/main.tsx b/src/main.tsx index 3cee194a..fdbb8fd6 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -18,7 +18,7 @@ if (import.meta.env.VITE_MOCK_API === 'true') { .start({ onUnhandledRequest: (request, print) => { // Let worker dismiss non-api calls by check whether url includes '/api' - if (!request.url.includes('/api')) { + if (!request.url.includes('/api') && !request.url.includes('/icon')) { console.log( "Dismissed request that doesn't include /api/: " + request.url, ); diff --git a/src/mocks/handlers/global.ts b/src/mocks/handlers/global.ts index 675b68a2..628aade4 100644 --- a/src/mocks/handlers/global.ts +++ b/src/mocks/handlers/global.ts @@ -2,6 +2,8 @@ import { http, HttpResponse } from 'msw'; import { customizeHandlers } from './customize'; import { memberHandlers } from './member'; import { pollHandlers } from './poll'; +import { organizationHandlers } from './organization'; +import { staticAssetHandlers } from './static_asset'; const TRANSLATIONS: Record> = { ko: { @@ -45,4 +47,6 @@ export const allHandlers = [ ...memberHandlers, ...customizeHandlers, ...pollHandlers, + ...organizationHandlers, + ...staticAssetHandlers, ]; diff --git a/src/mocks/handlers/organization.ts b/src/mocks/handlers/organization.ts new file mode 100644 index 00000000..e6b3968b --- /dev/null +++ b/src/mocks/handlers/organization.ts @@ -0,0 +1,42 @@ +import { http, HttpResponse } from 'msw'; +import { ApiUrl } from '../../apis/endpoints'; + +export const organizationHandlers = [ + // GET /api/organizations/templates + http.get(ApiUrl.organization + '/templates', () => { + return HttpResponse.json({ + organizations: [ + { + organization: '한앎', + affiliation: '한양대', + iconPath: '/icon/icon1.png', + templates: [ + { + name: '템플릿1', + data: 'eJyrVspMUbIytjDXUcrMS8tXsqpWykvMTVWyUjJWKCtWMFZ427b1TXPj27YFrxcueN3T8HZWj8LbGVPfdM9V0lEqqSwAqXQODQ7x9%2FWMcgUKJaan5qUkAgWB7IKi%2FOKQ1MRcP4iBbzasedOyESienJ%2BHLP56wwygwUDx8sSivMy8dKfUnBwlq7TEnOJUHaW0zLzM4gwkoVqgtYlJOUCN0dVKxSWJeckgMwKC%2FIOBJhQXpKYmZ4RAnPVmXivQzUDRpPwKqJCff5Cvow%2FI5Zkgqw2NDICyYLPzSnNyIMIBqUUgx6EJBRekJmYDHQcTLgbxU4sg3FodJKc4%2B%2FsNFqf4uYaGBIEtQXPNhDdzFkCiFMVNIZ6%2BrvFOjsGuLnB3QazA6TBzkLMx3AX2DIkhtHXOm0WtCq83zHkzbQfdAwpr8qG7i2JrAbdLRw0%3D', + }, + { + name: '템플릿2', + data: 'eJyrVspMUbIytjDXUcrMS8tXsqpWykvMTVWyUjJWKCtWMFZ427b1TXPj27YFrxcueN3T8HZWj8LbGVPfdM9V0lEqqSwAqXQODQ7x9%2FWMcgUKJaan5qUkAgWB7IKi%2FOKQ1MRcP4iBbzasedOyESienJ%2BHLP56wwygwUDx8sSivMy8dKfUnBwlq7TEnOJUHaW0zLzM4gwkoVqgtYlJOUCN0dVKxSWJeckgMwKC%2FIOBJhQXpKYmZ4RAnPVmXivQzUDRpPwKqJCff5Cvow%2FI5Zkgqw2NDICyYLPzSnNyIMIBqUUgx6EJBRekJmYDHQcTLgbxU4sg3FodJKc4%2B%2FsNFqf4uYaGBIEtQXPNhDdzFkCiFMVNIZ6%2BrvFOjsGuLnB3QazA6TBzkLMx3AX2DIkhtHXOm0WtCq83zHkzbQfdAwpr8qG7i2JrAbdLRw0%3D', + }, + ], + }, + { + organization: '한모름', + affiliation: '양한대', + iconPath: '/icon/icon2.png', + templates: [ + { + name: '템플릿1', + data: 'eJyrVspMUbIytjDXUcrMS8tXsqpWykvMTVWyUjJWKCtWMFZ427b1TXPj27YFrxcueN3T8HZWj8LbGVPfdM9V0lEqqSwAqXQODQ7x9%2FWMcgUKJaan5qUkAgWB7IKi%2FOKQ1MRcP4iBbzasedOyESienJ%2BHLP56wwygwUDx8sSivMy8dKfUnBwlq7TEnOJUHaW0zLzM4gwkoVqgtYlJOUCN0dVKxSWJeckgMwKC%2FIOBJhQXpKYmZ4RAnPVmXivQzUDRpPwKqJCff5Cvow%2FI5Zkgqw2NDICyYLPzSnNyIMIBqUUgx6EJBRekJmYDHQcTLgbxU4sg3FodJKc4%2B%2FsNFqf4uYaGBIEtQXPNhDdzFkCiFMVNIZ6%2BrvFOjsGuLnB3QazA6TBzkLMx3AX2DIkhtHXOm0WtCq83zHkzbQfdAwpr8qG7i2JrAbdLRw0%3D', + }, + { + name: '템플릿2', + data: 'eJyrVspMUbIytjDXUcrMS8tXsqpWykvMTVWyUjJWKCtWMFZ427b1TXPj27YFrxcueN3T8HZWj8LbGVPfdM9V0lEqqSwAqXQODQ7x9%2FWMcgUKJaan5qUkAgWB7IKi%2FOKQ1MRcP4iBbzasedOyESienJ%2BHLP56wwygwUDx8sSivMy8dKfUnBwlq7TEnOJUHaW0zLzM4gwkoVqgtYlJOUCN0dVKxSWJeckgMwKC%2FIOBJhQXpKYmZ4RAnPVmXivQzUDRpPwKqJCff5Cvow%2FI5Zkgqw2NDICyYLPzSnNyIMIBqUUgx6EJBRekJmYDHQcTLgbxU4sg3FodJKc4%2B%2FsNFqf4uYaGBIEtQXPNhDdzFkCiFMVNIZ6%2BrvFOjsGuLnB3QazA6TBzkLMx3AX2DIkhtHXOm0WtCq83zHkzbQfdAwpr8qG7i2JrAbdLRw0%3D', + }, + ], + }, + ], + }); + }), +]; diff --git a/src/mocks/handlers/static_asset.ts b/src/mocks/handlers/static_asset.ts new file mode 100644 index 00000000..1ad561b4 --- /dev/null +++ b/src/mocks/handlers/static_asset.ts @@ -0,0 +1,31 @@ +import { http, HttpResponse } from 'msw'; +import sampleLogo from '../../assets/template_logo/government.png'; + +const baseUrl = import.meta.env.VITE_API_BASE_URL || ''; + +export const staticAssetHandlers = [ + http.get(baseUrl + '/icon/:iconFileName', async ({ params }) => { + const { iconFileName } = params; + console.log(`# Requested icon file's name = ${iconFileName}`); + + const targetLocalImage = sampleLogo; + + try { + // 로컬 이미지 에셋을 ArrayBuffer의 형태로 불러옴 + const imageResponse = await fetch(targetLocalImage); + const imageBuffer = await imageResponse.arrayBuffer(); + const contentType = 'image/png'; + + // 실제 이미지 응답처럼 ArrayBuffer와 헤더를 반환 + return HttpResponse.arrayBuffer(imageBuffer, { + headers: { + 'Content-Type': contentType, + 'Cache-Control': 'max-age=31536000, immutable', // S3-like cache header + }, + }); + } catch (error) { + console.error('Failed to load mock image asset:', error); + return new HttpResponse(null, { status: 500 }); + } + }), +]; diff --git a/src/page/LandingPage/components/TemplateCard.tsx b/src/page/LandingPage/components/TemplateCard.tsx index f0ee93dd..c6227ead 100644 --- a/src/page/LandingPage/components/TemplateCard.tsx +++ b/src/page/LandingPage/components/TemplateCard.tsx @@ -1,15 +1,20 @@ import { useTranslation } from 'react-i18next'; -import { DebateTemplate } from '../../../type/type'; +import { Organization } from '../../../type/type'; import clsx from 'clsx'; +import { createTableShareUrlFromEncodedData } from '../../../util/arrayEncoding'; + +interface TemplateCardProps { + organization: Organization; + className?: string; // 카드의 추가 className이 필요하면 사용 +} export default function TemplateCard({ - title, - subtitle, - logoSrc, - actions, - className, -}: DebateTemplate) { + organization, + className = '', +}: TemplateCardProps) { const { t } = useTranslation(); + const logoUrl = import.meta.env.VITE_API_BASE_URL + organization.iconPath; + return (

- {title} + {organization.organization}

- {subtitle ?? ''} + {organization.affiliation}

{/* 로고 */} - {logoSrc && ( + {organization.iconPath && ( {t('{{title}} )} @@ -42,17 +47,17 @@ export default function TemplateCard({ {/* 액션 리스트 */}
    - {actions.map((action, index) => ( -
  • + {organization.templates.map((template, index) => ( +
  • - {action.label} + {template.name} {t('토론하기')} diff --git a/src/page/LandingPage/components/TemplateList.tsx b/src/page/LandingPage/components/TemplateList.tsx index 495ce882..a67340db 100644 --- a/src/page/LandingPage/components/TemplateList.tsx +++ b/src/page/LandingPage/components/TemplateList.tsx @@ -1,16 +1,20 @@ -import { DebateTemplate } from '../../../type/type'; +import { Organization } from '../../../type/type'; import TemplateCard from './TemplateCard'; interface TemplateListProps { - data: DebateTemplate[]; + organizations: Organization[]; } -export default function TemplateList({ data }: TemplateListProps) { + +export default function TemplateList({ organizations }: TemplateListProps) { return (
    - {data.map((template) => ( - + {organizations.map((organization) => ( + ))}
    ); diff --git a/src/page/LandingPage/components/TemplateSelection.tsx b/src/page/LandingPage/components/TemplateSelection.tsx index a238875f..bbee34a1 100644 --- a/src/page/LandingPage/components/TemplateSelection.tsx +++ b/src/page/LandingPage/components/TemplateSelection.tsx @@ -1,10 +1,14 @@ import { useTranslation } from 'react-i18next'; -import { DEBATE_TEMPLATE } from '../../../constants/debate_template'; import TemplateApplicationSection from './TemplateApplicationSection'; import TemplateList from './TemplateList'; +import { useGetOrganizationTemplates } from '../../../hooks/query/useGetOrganizationTemplates'; +import LoadingSpinner from '../../../components/LoadingSpinner'; +import ErrorIndicator from '../../../components/ErrorIndicator/ErrorIndicator'; export default function TemplateSelection() { const { t } = useTranslation(); + const { data, isError } = useGetOrganizationTemplates(); + return (
    @@ -12,11 +16,47 @@ export default function TemplateSelection() { {t('다양한 토론 템플릿을 원클릭으로 만나보세요!')}
    - -
    {/* 구분선 */} - -
    - + {isError ? ( +
    + + {t('템플릿을 불러오지 못했습니다. 잠시 후 다시 시도해주세요.')} + +
    + ) : data ? ( + <> + orgs.templates.length == 1, + )} + /> +
    + orgs.templates.length == 2, + )} + /> +
    + orgs.templates.length >= 3, + )} + /> + + ) : ( +
    + +

    + {t('템플릿을 불러오는 중입니다...')} +

    +
    + )}
    ); diff --git a/src/page/LandingPage/hooks/useLandingPageHandlers.ts b/src/page/LandingPage/hooks/useLandingPageHandlers.ts index 7f3508a4..576fdb80 100644 --- a/src/page/LandingPage/hooks/useLandingPageHandlers.ts +++ b/src/page/LandingPage/hooks/useLandingPageHandlers.ts @@ -2,7 +2,7 @@ import { useNavigate } from 'react-router-dom'; import { isLoggedIn } from '../../../util/accessToken'; import { oAuthLogin } from '../../../util/googleAuth'; import useLogout from '../../../hooks/mutations/useLogout'; -import { createTableShareUrl } from '../../../util/arrayEncoding'; +import { createTableShareUrlFromTable } from '../../../util/arrayEncoding'; import { SAMPLE_TABLE_DATA } from '../../../constants/sample_table'; import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; @@ -25,7 +25,7 @@ const useLandingPageHandlers = () => { // Declare functions that represent business logics const handleStartWithoutLogin = useCallback(() => { // window.location.href = LANDING_URLS.START_WITHOUT_LOGIN_URL; - window.location.href = createTableShareUrl( + window.location.href = createTableShareUrlFromTable( import.meta.env.VITE_SHARE_BASE_URL, SAMPLE_TABLE_DATA, ); diff --git a/src/type/type.ts b/src/type/type.ts index f96e5f7e..0d2d9ef4 100644 --- a/src/type/type.ts +++ b/src/type/type.ts @@ -91,17 +91,16 @@ export const bgColorMap: Record = { expired: 'bg-default-timeout', // 0초 이하 }; -type Action = { - label: string; // 좌측에 표시할 토론 형식 이름 (예: "CEDA 토론") - href: string; // 우측 "토론하기" 버튼의 이동 링크 +export type DebateTemplate = { + name: string; // 템플릿 이름 + data: string; // 인코딩된 템플릿 데이터 }; -export type DebateTemplate = { - title: string; // 제목 (예: "서방정토") - subtitle?: string; // 서브 제목 (예: "서강대") - logoSrc?: string; // 로고 이미지 - actions: Action[]; - className?: string; // 카드의 추가 className이 필요하면 사용 +export type Organization = { + organization: string; // 소분류 (e.g., 한앎) + affiliation: string; // 대분류 (e.g., 한양대) + iconPath: string; + templates: DebateTemplate[]; }; type TeamStyleConfig = { diff --git a/src/util/arrayEncoding.test.ts b/src/util/arrayEncoding.test.ts index cdb4e985..1e0527cf 100644 --- a/src/util/arrayEncoding.test.ts +++ b/src/util/arrayEncoding.test.ts @@ -1,6 +1,7 @@ import { DebateTableData } from '../type/type'; import { - createTableShareUrl, + createTableShareUrlFromEncodedData, + createTableShareUrlFromTable, decodeDebateTableData, encodeDebateTableData, extractTableShareUrl, @@ -99,9 +100,9 @@ describe('토론 테이블 인코딩 유틸리티', () => { expect(() => decodeURIComponent(encoded)).not.toThrow(); }); - test('createEncodedURL 함수는 data 쿼리 파라미터가 포함된 올바른 URL을 생성해야 한다', () => { + test('createTableShareUrlFromTable 함수는 data 쿼리 파라미터가 포함된 올바른 URL을 생성해야 한다', () => { const baseUrl = 'https://example.com/'; - const url = createTableShareUrl(baseUrl, sampleData); + const url = createTableShareUrlFromTable(baseUrl, sampleData); const parsed = new URL(url); const encodedData = parsed.searchParams.get('data'); expect(encodedData).toBeTruthy(); @@ -109,8 +110,21 @@ describe('토론 테이블 인코딩 유틸리티', () => { expect(decoded).toEqual(sampleData); }); + test('createTableShareUrlFromEncodedData 함수도 data 쿼리 파라미터가 포함된 올바른 URL을 생성해야 한다', () => { + const encodedData = encodeDebateTableData(sampleData); + const url = createTableShareUrlFromEncodedData(encodedData); + const parsed = new URL(url); + const decodedData = parsed.searchParams.get('data'); + expect(decodedData).toBeTruthy(); + const decoded = decodeDebateTableData(decodedData!); + expect(decoded).toEqual(sampleData); + }); + test('정상적인 URL에서 데이터를 추출하고 디코드할 수 있어야 한다', () => { - const url = createTableShareUrl('https://example.com/', sampleData); + const url = createTableShareUrlFromTable( + 'https://example.com/', + sampleData, + ); const result = extractTableShareUrl(url); expect(result).toEqual(sampleData); }); diff --git a/src/util/arrayEncoding.ts b/src/util/arrayEncoding.ts index a96c30bc..02b5544d 100644 --- a/src/util/arrayEncoding.ts +++ b/src/util/arrayEncoding.ts @@ -20,7 +20,7 @@ export function decodeDebateTableData(encodedData: string): DebateTableData { } } -export function createTableShareUrl( +export function createTableShareUrlFromTable( baseUrl: string | undefined, data: DebateTableData, ): string { @@ -33,6 +33,16 @@ export function createTableShareUrl( return `${normalizedBaseUrl}${pathPrefix}/share?data=${encoded}`; } +export function createTableShareUrlFromEncodedData(encodeData: string): string { + const baseUrl = import.meta.env.VITE_SHARE_BASE_URL || window.location.origin; + const resolvedBaseUrl = + baseUrl && baseUrl.trim() !== '' ? baseUrl : window.location.origin; + const normalizedBaseUrl = resolvedBaseUrl.replace(/\/+$/, ''); + const basePath = import.meta.env.VITE_BASE_PATH; + const pathPrefix = basePath && basePath !== '/' ? basePath : ''; + return `${normalizedBaseUrl}${pathPrefix}/share?data=${encodeData}`; +} + export function extractTableShareUrl(url: string): DebateTableData | null { try { const parsed = new URL(url);