@rpg-engine/long-bow 0.8.231 → 0.8.232

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/components/Quests/QuestInfo/QuestInfo.d.ts +3 -1
  2. package/dist/components/Quests/QuestInfo/QuestObjectivesSection.d.ts +8 -0
  3. package/dist/components/Quests/QuestInfo/QuestRequirementsSection.d.ts +8 -0
  4. package/dist/components/Quests/QuestInfo/QuestRewardsSection.d.ts +8 -0
  5. package/dist/components/Quests/QuestInfo/QuestSectionTypes.d.ts +8 -0
  6. package/dist/components/Quests/QuestList.d.ts +4 -5
  7. package/dist/components/Quests/QuestListRow.d.ts +15 -0
  8. package/dist/components/Tutorial/TutorialStepper.d.ts +2 -0
  9. package/dist/index.d.ts +1 -0
  10. package/dist/long-bow.cjs.development.js +435 -138
  11. package/dist/long-bow.cjs.development.js.map +1 -1
  12. package/dist/long-bow.cjs.production.min.js +1 -1
  13. package/dist/long-bow.cjs.production.min.js.map +1 -1
  14. package/dist/long-bow.esm.js +436 -140
  15. package/dist/long-bow.esm.js.map +1 -1
  16. package/package.json +1 -1
  17. package/src/components/Quests/QuestInfo/QuestInfo.tsx +57 -68
  18. package/src/components/Quests/QuestInfo/QuestObjectivesSection.tsx +114 -0
  19. package/src/components/Quests/QuestInfo/QuestRequirementsSection.tsx +74 -0
  20. package/src/components/Quests/QuestInfo/QuestRewardsSection.tsx +128 -0
  21. package/src/components/Quests/QuestInfo/QuestSectionTypes.ts +8 -0
  22. package/src/components/Quests/QuestList.tsx +12 -87
  23. package/src/components/Quests/QuestListRow.tsx +178 -0
  24. package/src/components/Store/CartView.tsx +3 -2
  25. package/src/components/Store/MetadataCollector.tsx +28 -1
  26. package/src/components/Store/__test__/MetadataCollector.spec.tsx +12 -3
  27. package/src/components/Tutorial/TutorialStepper.tsx +2 -0
  28. package/src/index.tsx +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpg-engine/long-bow",
3
- "version": "0.8.231",
3
+ "version": "0.8.232",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -10,14 +10,19 @@ import { DraggableContainer } from '../../DraggableContainer';
10
10
  import { RPGUIContainerTypes } from '../../RPGUI/RPGUIContainer';
11
11
  import { Column } from '../../shared/Column';
12
12
  import thumbnailDefault from './img/default.png';
13
+ import { QuestObjectivesSection } from './QuestObjectivesSection';
14
+ import { QuestRequirementsSection } from './QuestRequirementsSection';
15
+ import { QuestRewardsSection } from './QuestRewardsSection';
16
+ import { IQuestAtlasProps } from './QuestSectionTypes';
13
17
 
14
18
  export interface IQuestsButtonProps {
15
19
  disabled: boolean;
20
+ disabledReason?: string;
16
21
  title: string;
17
22
  onClick: (questId: string, npcId: string) => void;
18
23
  }
19
24
 
20
- export interface IQuestInfoProps {
25
+ export interface IQuestInfoProps extends IQuestAtlasProps {
21
26
  onClose?: () => void;
22
27
  buttons?: IQuestsButtonProps[];
23
28
  quests: IQuest[];
@@ -31,15 +36,22 @@ export const QuestInfo: React.FC<IQuestInfoProps> = ({
31
36
  buttons,
32
37
  onChangeQuest,
33
38
  scale,
39
+ itemsAtlasJSON,
40
+ itemsAtlasIMG,
41
+ entitiesAtlasJSON,
42
+ entitiesAtlasIMG,
43
+ iconsAtlasJSON,
44
+ iconsAtlasIMG,
34
45
  }) => {
35
46
  const [currentIndex, setCurrentIndex] = useState(0);
36
47
  const questsLength = quests.length - 1;
48
+ const currentQuest = quests[currentIndex] || quests[0];
37
49
 
38
50
  useEffect(() => {
39
- if (onChangeQuest) {
40
- onChangeQuest(currentIndex, quests[currentIndex]._id);
51
+ if (onChangeQuest && currentQuest) {
52
+ onChangeQuest(currentIndex, currentQuest._id);
41
53
  }
42
- }, [currentIndex]);
54
+ }, [currentIndex, currentQuest]);
43
55
 
44
56
  const onLeftClick = () => {
45
57
  if (currentIndex === 0) setCurrentIndex(questsLength);
@@ -60,86 +72,59 @@ export const QuestInfo: React.FC<IQuestInfoProps> = ({
60
72
  cancelDrag=".equipment-container-body .arrow-selector"
61
73
  scale={scale}
62
74
  >
63
- {quests.length >= 2 ? (
75
+ {currentQuest && (
64
76
  <QuestsContainer>
65
- {currentIndex !== 0 && (
66
- <SelectArrow
67
- direction="left"
68
- onPointerDown={onLeftClick}
69
- ></SelectArrow>
77
+ {quests.length >= 2 && currentIndex !== 0 && (
78
+ <SelectArrow direction="left" onPointerDown={onLeftClick} />
70
79
  )}
71
- {currentIndex !== quests.length - 1 && (
72
- <SelectArrow
73
- direction="right"
74
- onPointerDown={onRightClick}
75
- ></SelectArrow>
80
+ {quests.length >= 2 && currentIndex !== quests.length - 1 && (
81
+ <SelectArrow direction="right" onPointerDown={onRightClick} />
76
82
  )}
77
-
78
83
  <QuestContainer>
79
84
  <TitleContainer className="drag-handler">
80
85
  <Title>
81
- <Thumbnail
82
- src={quests[currentIndex].thumbnail || thumbnailDefault}
83
- />
84
- {quests[currentIndex].title}
86
+ <Thumbnail src={currentQuest.thumbnail || thumbnailDefault} />
87
+ {currentQuest.title}
85
88
  </Title>
86
89
  <QuestSplitDiv>
87
90
  <hr className="golden" />
88
91
  </QuestSplitDiv>
89
92
  </TitleContainer>
90
93
  <Content>
91
- <p>{quests[currentIndex].description}</p>
94
+ <p>{currentQuest.description}</p>
92
95
  </Content>
96
+ <QuestObjectivesSection
97
+ objectives={currentQuest.objectives as any}
98
+ entitiesAtlasJSON={entitiesAtlasJSON}
99
+ entitiesAtlasIMG={entitiesAtlasIMG}
100
+ />
101
+ <QuestRequirementsSection
102
+ objectives={currentQuest.objectives as any}
103
+ itemsAtlasJSON={itemsAtlasJSON}
104
+ itemsAtlasIMG={itemsAtlasIMG}
105
+ />
106
+ <QuestRewardsSection
107
+ rewards={currentQuest.rewards}
108
+ itemsAtlasJSON={itemsAtlasJSON}
109
+ itemsAtlasIMG={itemsAtlasIMG}
110
+ iconsAtlasJSON={iconsAtlasJSON}
111
+ iconsAtlasIMG={iconsAtlasIMG}
112
+ />
93
113
  <QuestColumn className="dark-background" justifyContent="flex-end">
94
114
  {buttons &&
95
115
  buttons.map((button, index) => (
96
- <Button
97
- key={index}
98
- onPointerDown={() =>
99
- button.onClick(
100
- quests[currentIndex]._id,
101
- quests[currentIndex].npcId
102
- )
103
- }
104
- disabled={button.disabled}
105
- buttonType={ButtonTypes.RPGUIButton}
106
- id={`button-${index}`}
107
- >
108
- {button.title}
109
- </Button>
110
- ))}
111
- </QuestColumn>
112
- </QuestContainer>
113
- </QuestsContainer>
114
- ) : (
115
- <QuestsContainer>
116
- <QuestContainer>
117
- <TitleContainer className="drag-handler">
118
- <Title>
119
- <Thumbnail src={quests[0].thumbnail || thumbnailDefault} />
120
- {quests[0].title}
121
- </Title>
122
- <QuestSplitDiv>
123
- <hr className="golden" />
124
- </QuestSplitDiv>
125
- </TitleContainer>
126
- <Content>
127
- <p>{quests[0].description}</p>
128
- </Content>
129
- <QuestColumn className="dark-background" justifyContent="flex-end">
130
- {buttons &&
131
- buttons.map((button, index) => (
132
- <Button
133
- key={index}
134
- onPointerDown={() =>
135
- button.onClick(quests[0]._id, quests[0].npcId)
136
- }
137
- disabled={button.disabled}
138
- buttonType={ButtonTypes.RPGUIButton}
139
- id={`button-${index}`}
140
- >
141
- {button.title}
142
- </Button>
116
+ <ButtonWrapper key={index} title={button.disabled ? button.disabledReason : undefined}>
117
+ <Button
118
+ onPointerDown={() =>
119
+ button.onClick(currentQuest._id, currentQuest.npcId)
120
+ }
121
+ disabled={button.disabled}
122
+ buttonType={ButtonTypes.RPGUIButton}
123
+ id={`button-${index}`}
124
+ >
125
+ {button.title}
126
+ </Button>
127
+ </ButtonWrapper>
143
128
  ))}
144
129
  </QuestColumn>
145
130
  </QuestContainer>
@@ -207,6 +192,10 @@ const QuestColumn = styled(Column)`
207
192
  justify-content: space-evenly;
208
193
  `;
209
194
 
195
+ const ButtonWrapper = styled.div`
196
+ display: inline-flex;
197
+ `;
198
+
210
199
  const TitleContainer = styled.div`
211
200
  width: 100%;
212
201
  display: flex;
@@ -0,0 +1,114 @@
1
+ import { IQuestObjectiveInteraction, IQuestObjectiveKill, QuestType } from '@rpg-engine/shared';
2
+ import React from 'react';
3
+ import styled from 'styled-components';
4
+ import { uiColors } from '../../../constants/uiColors';
5
+ import { SpriteFromAtlas } from '../../shared/SpriteFromAtlas';
6
+ import { IQuestAtlasProps } from './QuestSectionTypes';
7
+
8
+ interface IProps extends IQuestAtlasProps {
9
+ objectives?: Array<IQuestObjectiveKill | IQuestObjectiveInteraction>;
10
+ }
11
+
12
+ export const QuestObjectivesSection: React.FC<IProps> = ({
13
+ objectives = [],
14
+ entitiesAtlasJSON,
15
+ entitiesAtlasIMG,
16
+ }) => {
17
+ if (!objectives.length) {
18
+ return null;
19
+ }
20
+
21
+ return (
22
+ <Section>
23
+ <SectionTitle>Objectives</SectionTitle>
24
+ {objectives.map((objective: any, index) => {
25
+ if (objective.type === QuestType.Kill) {
26
+ const progress = `${objective.killCount || 0}/${objective.killCountTarget}`;
27
+ const fill = Math.min((objective.killCount || 0) / Math.max(objective.killCountTarget || 1, 1), 1) * 100;
28
+
29
+ return (
30
+ <ObjectiveBlock key={objective.id || index}>
31
+ {(objective.creatures || objective.creatureKeys || []).map((creature: any) => {
32
+ const data = typeof creature === 'string' ? { key: creature, name: creature, texturePath: '' } : creature;
33
+ return (
34
+ <ObjectiveRow key={data.key}>
35
+ {entitiesAtlasJSON && entitiesAtlasIMG && data.texturePath && (
36
+ <SpriteFromAtlas
37
+ atlasJSON={entitiesAtlasJSON}
38
+ atlasIMG={entitiesAtlasIMG}
39
+ spriteKey={data.texturePath}
40
+ width={32}
41
+ height={32}
42
+ imgScale={1}
43
+ centered
44
+ />
45
+ )}
46
+ <ObjectiveText>{data.name || data.key}</ObjectiveText>
47
+ <ProgressText>{progress}</ProgressText>
48
+ </ObjectiveRow>
49
+ );
50
+ })}
51
+ <ProgressBar>
52
+ <ProgressFill style={{ width: `${fill}%` }} />
53
+ </ProgressBar>
54
+ </ObjectiveBlock>
55
+ );
56
+ }
57
+
58
+ if (objective.type === QuestType.Interaction) {
59
+ return (
60
+ <ObjectiveRow key={objective.id || index}>
61
+ <ObjectiveText>Talk to {objective.targetNPCkey || 'the quest contact'}</ObjectiveText>
62
+ </ObjectiveRow>
63
+ );
64
+ }
65
+
66
+ return null;
67
+ })}
68
+ </Section>
69
+ );
70
+ };
71
+
72
+ const Section = styled.section`
73
+ margin: 10px 18px;
74
+ `;
75
+
76
+ const SectionTitle = styled.h2`
77
+ color: ${uiColors.yellow};
78
+ font-size: 0.9rem;
79
+ margin: 0 0 8px;
80
+ `;
81
+
82
+ const ObjectiveBlock = styled.div`
83
+ margin-bottom: 8px;
84
+ `;
85
+
86
+ const ObjectiveRow = styled.div`
87
+ color: ${uiColors.white};
88
+ display: flex;
89
+ align-items: center;
90
+ gap: 8px;
91
+ min-height: 28px;
92
+ font-size: 0.75rem;
93
+ `;
94
+
95
+ const ObjectiveText = styled.span`
96
+ flex: 1;
97
+ `;
98
+
99
+ const ProgressText = styled.span`
100
+ color: ${uiColors.yellow};
101
+ `;
102
+
103
+ const ProgressBar = styled.div`
104
+ height: 6px;
105
+ background: ${uiColors.gray};
106
+ border-radius: 3px;
107
+ overflow: hidden;
108
+ margin-top: 4px;
109
+ `;
110
+
111
+ const ProgressFill = styled.div`
112
+ height: 100%;
113
+ background: ${uiColors.lightGreen};
114
+ `;
@@ -0,0 +1,74 @@
1
+ import { IQuestObjectiveInteraction, QuestType } from '@rpg-engine/shared';
2
+ import React from 'react';
3
+ import styled from 'styled-components';
4
+ import { uiColors } from '../../../constants/uiColors';
5
+ import { ItemInfoWrapper } from '../../Item/Cards/ItemInfoWrapper';
6
+ import { SpriteFromAtlas } from '../../shared/SpriteFromAtlas';
7
+ import { IQuestAtlasProps } from './QuestSectionTypes';
8
+
9
+ interface IProps extends IQuestAtlasProps {
10
+ objectives?: IQuestObjectiveInteraction[];
11
+ }
12
+
13
+ export const QuestRequirementsSection: React.FC<IProps> = ({
14
+ objectives = [],
15
+ itemsAtlasJSON,
16
+ itemsAtlasIMG,
17
+ }) => {
18
+ const items = objectives
19
+ .filter((objective: any) => objective.type === QuestType.Interaction)
20
+ .flatMap((objective: any) => objective.items || []);
21
+
22
+ if (!items.length) {
23
+ return null;
24
+ }
25
+
26
+ return (
27
+ <Section>
28
+ <SectionTitle>Requirements</SectionTitle>
29
+ {items.map((item: any) => {
30
+ const hasQty = item.playerHasQty || 0;
31
+ const isMet = hasQty >= item.qty;
32
+ return (
33
+ <RequirementRow key={item.itemKey} isMet={isMet}>
34
+ {itemsAtlasJSON && itemsAtlasIMG && item.texturePath && (
35
+ <ItemInfoWrapper item={{ ...item, key: item.itemKey, stackQty: item.qty } as any} atlasJSON={itemsAtlasJSON} atlasIMG={itemsAtlasIMG}>
36
+ <SpriteFromAtlas
37
+ atlasJSON={itemsAtlasJSON}
38
+ atlasIMG={itemsAtlasIMG}
39
+ spriteKey={item.texturePath}
40
+ width={32}
41
+ height={32}
42
+ imgScale={1.5}
43
+ centered
44
+ />
45
+ </ItemInfoWrapper>
46
+ )}
47
+ <span>
48
+ {hasQty}/{item.qty} {item.name || item.itemKey}
49
+ </span>
50
+ </RequirementRow>
51
+ );
52
+ })}
53
+ </Section>
54
+ );
55
+ };
56
+
57
+ const Section = styled.section`
58
+ margin: 10px 18px;
59
+ `;
60
+
61
+ const SectionTitle = styled.h2`
62
+ color: ${uiColors.yellow};
63
+ font-size: 0.9rem;
64
+ margin: 0 0 8px;
65
+ `;
66
+
67
+ const RequirementRow = styled.div<{ isMet: boolean }>`
68
+ color: ${(props) => (props.isMet ? uiColors.lightGreen : uiColors.red)};
69
+ display: flex;
70
+ align-items: center;
71
+ gap: 8px;
72
+ min-height: 34px;
73
+ font-size: 0.75rem;
74
+ `;
@@ -0,0 +1,128 @@
1
+ import { IQuestReward } from '@rpg-engine/shared';
2
+ import React from 'react';
3
+ import styled from 'styled-components';
4
+ import { uiColors } from '../../../constants/uiColors';
5
+ import { ItemInfoWrapper } from '../../Item/Cards/ItemInfoWrapper';
6
+ import { SpriteFromAtlas } from '../../shared/SpriteFromAtlas';
7
+ import { IQuestAtlasProps } from './QuestSectionTypes';
8
+
9
+ interface IProps extends IQuestAtlasProps {
10
+ rewards?: IQuestReward[];
11
+ }
12
+
13
+ export const QuestRewardsSection: React.FC<IProps> = ({
14
+ rewards = [],
15
+ itemsAtlasJSON,
16
+ itemsAtlasIMG,
17
+ iconsAtlasJSON,
18
+ iconsAtlasIMG,
19
+ }) => {
20
+ const items = rewards.flatMap((reward: any) => reward.items || []);
21
+ const spells = rewards.flatMap((reward: any) => reward.spells || []);
22
+
23
+ if (!items.length && !spells.length) {
24
+ return null;
25
+ }
26
+
27
+ return (
28
+ <Section>
29
+ <SectionTitle>Rewards</SectionTitle>
30
+ <RewardGrid>
31
+ {items.map((item: any) => (
32
+ <RewardItem key={`${item.key}-${item.qty}`}>
33
+ {itemsAtlasJSON && itemsAtlasIMG && item.texturePath ? (
34
+ <ItemInfoWrapper
35
+ item={{ ...item, key: item.key, stackQty: item.qty } as any}
36
+ atlasJSON={itemsAtlasJSON}
37
+ atlasIMG={itemsAtlasIMG}
38
+ >
39
+ <SpriteFromAtlas
40
+ atlasJSON={itemsAtlasJSON}
41
+ atlasIMG={itemsAtlasIMG}
42
+ spriteKey={item.texturePath}
43
+ width={32}
44
+ height={32}
45
+ imgScale={1.5}
46
+ centered
47
+ />
48
+ </ItemInfoWrapper>
49
+ ) : (
50
+ <FallbackIcon>{item.name?.[0] || '?'}</FallbackIcon>
51
+ )}
52
+ {item.qty > 1 && <QtyBadge>x{item.qty}</QtyBadge>}
53
+ <RewardName>{item.name || item.key}</RewardName>
54
+ </RewardItem>
55
+ ))}
56
+ {spells.map((spell: any) => (
57
+ <RewardItem key={spell.key} title={spell.name || spell.key}>
58
+ {iconsAtlasJSON && iconsAtlasIMG && spell.texturePath ? (
59
+ <SpriteFromAtlas
60
+ atlasJSON={iconsAtlasJSON}
61
+ atlasIMG={iconsAtlasIMG}
62
+ spriteKey={spell.texturePath}
63
+ width={32}
64
+ height={32}
65
+ imgScale={1.5}
66
+ centered
67
+ />
68
+ ) : (
69
+ <FallbackIcon>{spell.name?.[0] || '?'}</FallbackIcon>
70
+ )}
71
+ <RewardName>{spell.name || spell.key}</RewardName>
72
+ </RewardItem>
73
+ ))}
74
+ </RewardGrid>
75
+ </Section>
76
+ );
77
+ };
78
+
79
+ const Section = styled.section`
80
+ margin: 10px 18px;
81
+ `;
82
+
83
+ const SectionTitle = styled.h2`
84
+ color: ${uiColors.yellow};
85
+ font-size: 0.9rem;
86
+ margin: 0 0 8px;
87
+ `;
88
+
89
+ const RewardGrid = styled.div`
90
+ display: grid;
91
+ grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
92
+ gap: 8px;
93
+ `;
94
+
95
+ const RewardItem = styled.div`
96
+ position: relative;
97
+ min-height: 58px;
98
+ color: ${uiColors.white};
99
+ display: flex;
100
+ flex-direction: column;
101
+ align-items: center;
102
+ gap: 4px;
103
+ font-size: 0.65rem;
104
+ `;
105
+
106
+ const FallbackIcon = styled.div`
107
+ width: 32px;
108
+ height: 32px;
109
+ border: 1px solid ${uiColors.gray};
110
+ display: flex;
111
+ align-items: center;
112
+ justify-content: center;
113
+ color: ${uiColors.yellow};
114
+ `;
115
+
116
+ const QtyBadge = styled.span`
117
+ position: absolute;
118
+ top: 0;
119
+ right: 18px;
120
+ background: ${uiColors.darkGray};
121
+ color: ${uiColors.yellow};
122
+ border: 1px solid ${uiColors.gray};
123
+ padding: 1px 4px;
124
+ `;
125
+
126
+ const RewardName = styled.span`
127
+ text-align: center;
128
+ `;
@@ -0,0 +1,8 @@
1
+ export interface IQuestAtlasProps {
2
+ itemsAtlasJSON?: any;
3
+ itemsAtlasIMG?: any;
4
+ entitiesAtlasJSON?: any;
5
+ entitiesAtlasIMG?: any;
6
+ iconsAtlasJSON?: any;
7
+ iconsAtlasIMG?: any;
8
+ }
@@ -1,10 +1,12 @@
1
- import { IQuest, QuestStatus } from '@rpg-engine/shared';
1
+ import { IQuest } from '@rpg-engine/shared';
2
2
  import React from 'react';
3
3
  import styled, { CSSProperties } from 'styled-components';
4
4
  import { uiColors } from '../../constants/uiColors';
5
+ import { IQuestListAtlasProps, QuestListRow } from './QuestListRow';
5
6
 
6
- export interface IQuestListProps {
7
+ export interface IQuestListProps extends IQuestListAtlasProps {
7
8
  quests?: IQuest[];
9
+ compact?: boolean;
8
10
  styles?: {
9
11
  container?: CSSProperties;
10
12
  card?: CSSProperties;
@@ -13,34 +15,18 @@ export interface IQuestListProps {
13
15
  };
14
16
  }
15
17
 
16
- export const QuestList: React.FC<IQuestListProps> = ({ quests, styles }) => {
18
+ export const QuestList: React.FC<IQuestListProps> = ({ quests, compact, styles, itemsAtlasJSON, itemsAtlasIMG }) => {
17
19
  return (
18
20
  <QuestListContainer style={styles?.container}>
19
21
  {quests && quests.length > 0 ? (
20
22
  quests.map((quest, i) => (
21
- <QuestCard key={i} style={styles?.card}>
22
- <QuestItem>
23
- <Label style={styles?.label}>Title:</Label>
24
- <Value style={styles?.value}>
25
- {formatQuestText(quest.title)}
26
- </Value>
27
- </QuestItem>
28
- <QuestItem>
29
- <Label style={styles?.label}>Status:</Label>
30
- <Value
31
- style={{
32
- ...styles?.value,
33
- color: getQuestStatusColor(quest.status),
34
- }}
35
- >
36
- {formatQuestStatus(quest.status) ?? 'Unknown'}
37
- </Value>
38
- </QuestItem>
39
- <QuestItem>
40
- <Label style={styles?.label}>Description:</Label>
41
- <Value style={styles?.value}>{quest.description}</Value>
42
- </QuestItem>
43
- </QuestCard>
23
+ <QuestListRow
24
+ key={quest._id || i}
25
+ quest={quest}
26
+ compact={compact}
27
+ itemsAtlasJSON={itemsAtlasJSON}
28
+ itemsAtlasIMG={itemsAtlasIMG}
29
+ />
44
30
  ))
45
31
  ) : (
46
32
  <NoQuestContainer>
@@ -58,38 +44,6 @@ const QuestListContainer = styled.div`
58
44
  font-size: 0.7rem;
59
45
  `;
60
46
 
61
- const QuestCard = styled.div`
62
- background-color: ${uiColors.darkGray};
63
- padding: 15px;
64
- margin-bottom: 10px;
65
- border-radius: 10px;
66
- border: 1px solid ${uiColors.gray};
67
- display: flex;
68
- flex-direction: column;
69
- `;
70
-
71
- const QuestItem = styled.div`
72
- display: flex;
73
- margin-bottom: 5px;
74
- flex-wrap: wrap;
75
-
76
- &:last-child {
77
- margin-bottom: 0;
78
- }
79
- `;
80
-
81
- const Label = styled.span`
82
- font-weight: bold;
83
- color: ${uiColors.yellow} !important;
84
- margin-right: 10px;
85
- `;
86
-
87
- const Value = styled.span`
88
- flex-grow: 1;
89
- color: ${uiColors.white};
90
- word-wrap: break-word;
91
- `;
92
-
93
47
  const NoQuestContainer = styled.div`
94
48
  text-align: center;
95
49
  p {
@@ -97,32 +51,3 @@ const NoQuestContainer = styled.div`
97
51
  color: ${uiColors.lightGray};
98
52
  }
99
53
  `;
100
-
101
- export const formatQuestText = (text: string) => {
102
- if (!text) return '';
103
- return text
104
- .split('-')
105
- .map(word => word.charAt(0).toUpperCase() + word.slice(1))
106
- .join(' ');
107
- };
108
-
109
- export const getQuestStatusColor = (status?: QuestStatus) => {
110
- switch (status) {
111
- case QuestStatus.Pending:
112
- return uiColors.orange;
113
- case QuestStatus.InProgress:
114
- return uiColors.blue;
115
- case QuestStatus.Completed:
116
- return uiColors.lightGreen;
117
- default:
118
- return uiColors.white;
119
- }
120
- };
121
-
122
- export const formatQuestStatus = (status?: QuestStatus) => {
123
- if (!status) return '';
124
- return status
125
- .split(/(?=[A-Z])/)
126
- .join(' ')
127
- .replace(/^\w/, c => c.toUpperCase());
128
- };