Skip to content

Commit

Permalink
Merge pull request #29 from formsible/feat/redirect
Browse files Browse the repository at this point in the history
add component
  • Loading branch information
tewnut authored Oct 30, 2024
2 parents 3c18c26 + bb7b3d4 commit b6c06b0
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 52 deletions.
3 changes: 0 additions & 3 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ declare module 'vue' {
Address: typeof import('./src/components/address/index.vue')['default']
Appointment: typeof import('./src/components/appointment/index.vue')['default']
Audio_recorder: typeof import('./src/components/audio_recorder/index.vue')['default']
Button: typeof import('primevue/button')['default']
Captcha: typeof import('./src/components/captcha/index.vue')['default']
Checkboxes: typeof import('./src/components/checkboxes/index.vue')['default']
Code_javascript: typeof import('./src/components/code_javascript/index.vue')['default']
Expand All @@ -31,7 +30,6 @@ declare module 'vue' {
Html_block_list: typeof import('./src/components/html_block_list/index.vue')['default']
Html_block_media: typeof import('./src/components/html_block_media/index.vue')['default']
Image_choice: typeof import('./src/components/image_choice/index.vue')['default']
InputText: typeof import('primevue/inputtext')['default']
Likert_scale: typeof import('./src/components/likert_scale/index.vue')['default']
List: typeof import('./src/components/list/index.vue')['default']
Locale_selector: typeof import('./src/components/locale_selector/index.vue')['default']
Expand All @@ -51,7 +49,6 @@ declare module 'vue' {
Signature: typeof import('./src/components/signature/index.vue')['default']
Slider: typeof import('./src/components/slider/index.vue')['default']
Term_of_service: typeof import('./src/components/term_of_service/index.vue')['default']
Textarea: typeof import('primevue/textarea')['default']
Time_picker: typeof import('./src/components/time_picker/index.vue')['default']
Website: typeof import('./src/components/website/index.vue')['default']
}
Expand Down
7 changes: 6 additions & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@

<div class="w-1/2 overflow-auto p-4">
<h2 class="text-xl font-bold mb-4">Preview</h2>
<pre>{{ state }}</pre>
<ActionRedirect
:redirect="false"
:display="{ url: 'https://example.com' }"
/>
<Transition
mode="out-in"
enterActiveClass="transition duration-100 delay-100"
Expand All @@ -64,6 +67,7 @@
formComponents[currentComponentIndex].inputProps
?.error
"
:redirect="false"
/>
</Transition>
</div>
Expand Down Expand Up @@ -125,6 +129,7 @@ import {
} from 'vue'
import AppBar from './AppBar.vue'
import type { ElementManifest } from '~/types'
import { ActionRedirect } from '.'
const state = reactive<Record<string, unknown>>({})
interface IComponent {
Expand Down
35 changes: 21 additions & 14 deletions src/components/action_redirect/index.vue
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
<script setup lang="ts">
import { useTimeoutFn } from '@vueuse/core'
import { onMounted } from 'vue'
import { ref, watch } from 'vue'
import type { ActionRedirectProperties } from '~/types'
// Props declaration
interface Props {
display: ActionRedirectProperties
redirect?: boolean
}
const props = defineProps<Props>()
const props = withDefaults(defineProps<Props>(), {
redirect: true,
})
const secondsRemaining = ref(props.display.countDown || 3)
// Countdown complete event
const onCountdownComplete = () => {
window.location.href = props.display.url
}
const onCountdownComplete = () => (window.location.href = props.display.url)
// Timeout composable by vusue
const { start } = useTimeoutFn(
onCountdownComplete,
props.display.countDown || 3000,
)
// Interval for timer
setInterval(() => {
if (secondsRemaining.value > 0 && props.redirect === true)
secondsRemaining.value = secondsRemaining.value - 1
}, 1000)
// Hooks
onMounted(start)
// Watchers
watch(secondsRemaining, (newValue) => {
if (newValue <= 0) onCountdownComplete()
})
</script>
<template>
<div class="text-center">
<p>You are being directed to {{ display.url }}.</p>
<p>
You will be redirected in {{ secondsRemaining }} seconds to
{{ display.url }}.
</p>
</div>
</template>
7 changes: 6 additions & 1 deletion src/types/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export type InputComponentType =
| 'captcha'
| 'checkboxes'
| 'date_picker'
| 'list'
| 'dropdown'
| 'email'
| 'file_upload'
Expand All @@ -53,9 +54,13 @@ export type InputComponentType =
| 'rating_scale'
| 'short_text'
| 'signature'
| 'data_table'
| 'slider'
| 'time_picker'
| 'website';
| 'website'
| 'audio_recorder'
| 'code_javascript'
| 'code_json'

// ==============================
// Validation
Expand Down
47 changes: 38 additions & 9 deletions src/utils/display-components.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,42 @@
import { Component } from "vue";
import type { DisplayComponentType } from "~/types";
import { ActionRedirect, EmbedDocument, EmbedSlides, HtmlBlockContent, HtmlBlockList, HtmlBlockMedia, LocaleSelector } from "..";
import {
// Content Block Components
HtmlBlockContent,
HtmlBlockList,
HtmlBlockMedia,

// Embed Components
EmbedDocument,
EmbedSlides,

// Utility Components
LocaleSelector,
ActionRedirect,
} from "..";

/**
* A collection of display components for rendering various types of content.
* Each component is mapped to its corresponding DisplayComponentType.
*
* Components are grouped into the following categories:
* - Content Block: Components for rendering structured HTML content
* - Embed: Components for displaying external documents and presentations
* - Utility: Components for user interaction and navigation
*/
export const displayComponents: Record<DisplayComponentType, Component> = {
html_block_content: HtmlBlockContent,
html_block_list: HtmlBlockList,
html_block_media: HtmlBlockMedia,
locale_selector: LocaleSelector,
action_redirect: ActionRedirect,
embed_slide: EmbedSlides,
embed_document: EmbedDocument
}
// Content Block Components
html_block_content: HtmlBlockContent, // Renders formatted HTML content
html_block_list: HtmlBlockList, // Displays structured list content
html_block_media: HtmlBlockMedia, // Handles media content display

// Embed Components
embed_document: EmbedDocument, // Embeds external documents
embed_slide: EmbedSlides, // Embeds presentation slides

// Utility Components
locale_selector: LocaleSelector, // Language/locale selection interface
action_redirect: ActionRedirect, // Handles navigation redirects
};

export default displayComponents;
119 changes: 95 additions & 24 deletions src/utils/input-components.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,99 @@
import { Component } from "vue";
import type { InputComponentType } from "~/types";
import { Number, Address, Captcha, Checkboxes, DatePicker, Dropdown, Email, FileUpload, ImageChoice, LikertScale, LongText, MultipleChoice, NetPromoterScore, Password, PhoneNumber, Ranking, RatingScale, ShortText, Signature, Slider, TimePicker, Website } from '..'
import {
// Text Input Components
ShortText,
LongText,
Email,
Password,
Website,
PhoneNumber,
Address,

// Numeric Input Components
Number,
Slider,
RatingScale,
NetPromoterScore,
LikertScale,

// Selection Components
Dropdown,
MultipleChoice,
Checkboxes,
ImageChoice,
Ranking,

// Date & Time Components
DatePicker,
TimePicker,

// Media & File Components
FileUpload,
Signature,
AudioRecorder,

// Verification Components
Captcha,
List,
DataTable,
CodeJavascript,
CodeJson,
} from '..';

/**
* A collection of input components organized by type and functionality.
* Each component is mapped to its corresponding InputComponentType.
*
* Components are grouped into the following categories:
* - Text Input: Components for collecting various types of text data
* - Numeric Input: Components for collecting numerical data and ratings
* - Selection: Components for choosing from predefined options
* - Date & Time: Components for temporal data collection
* - Media & File: Components for handling file uploads and media recording
* - Verification: Components for user verification
*/
export const inputComponents: Record<InputComponentType, Component> = {
number: Number,
address: Address,
captcha: Captcha,
checkboxes: Checkboxes,
date_picker: DatePicker,
dropdown: Dropdown,
email: Email,
file_upload: FileUpload,
image_choice: ImageChoice,
likert_scale: LikertScale,
long_text: LongText,
multiple_choice: MultipleChoice,
net_promoter_score: NetPromoterScore,
password: Password,
phone_number: PhoneNumber,
ranking: Ranking,
rating_scale: RatingScale,
short_text: ShortText,
signature: Signature,
slider: Slider,
time_picker: TimePicker,
website: Website
}
// Text Input Components
short_text: ShortText, // Single-line text input
long_text: LongText, // Multi-line text input
email: Email, // Email address input with validation
password: Password, // Secure password input field
website: Website, // URL input with validation
phone_number: PhoneNumber, // Phone number input with formatting
address: Address, // Structured address input
code_javascript: CodeJavascript,
code_json: CodeJson,

// Numeric Input Components
number: Number, // Basic number input
slider: Slider, // Range selection using a slider
rating_scale: RatingScale, // Numeric rating (e.g., 1-5 stars)
net_promoter_score: NetPromoterScore, // 0-10 satisfaction score
likert_scale: LikertScale, // Agreement scale (e.g., strongly disagree to strongly agree)

// Selection Components
dropdown: Dropdown, // Single selection from dropdown
multiple_choice: MultipleChoice, // Single selection from radio buttons
checkboxes: Checkboxes, // Multiple selection from checkboxes
image_choice: ImageChoice, // Selection from image options
ranking: Ranking, // Ordered ranking of options

// List Components
list: List,
data_table: DataTable,

// Date & Time Components
date_picker: DatePicker, // Date selection calendar
time_picker: TimePicker, // Time selection input

// Media & File Components
file_upload: FileUpload, // File upload functionality
signature: Signature, // Digital signature capture
audio_recorder: AudioRecorder, // Audio recording functionality

// Verification Components
captcha: Captcha, // CAPTCHA verification
};

export default inputComponents;

0 comments on commit b6c06b0

Please sign in to comment.