Documentation Index
Fetch the complete documentation index at: https://mintlify.com/BhushanBadhe39/SkinFirts/llms.txt
Use this file to discover all available pages before exploring further.
SkinFirts ships a focused library of reusable React Native components that cover every recurring pattern in the app — action buttons, text inputs, doctor cards, chat bubbles, schedule views, and navigation headers. All components are styled using the shared theme tokens (colors, fonts, metrics) so visual updates propagate automatically across the entire app. Import any component directly from src/components/.
A circular pressable button that renders an Ionicons icon centered inside a filled circle. Used throughout the app for icon-only actions such as the back button, favorite toggle row, and help icons inside cards.
| Prop | Type | Default | Description |
|---|
iconName | string | — | Any valid Ionicons icon name (e.g. 'heart-outline') |
size | number | — | Diameter of the circle and the touch target (icon renders at size * 0.6) |
color | string | colors.primary | Icon tint color |
bgc | string | colors.shade | Circle background color |
onPress | function | — | Callback fired on press |
import RoundButtons from '../components/RoundButtons';
import { colors } from '../theme/colors';
import { scale } from '../theme/metrics';
<RoundButtons
iconName="notifications-outline"
size={scale(40)}
color={colors.primary}
bgc={colors.shadeLight}
onPress={() => console.log('notifications pressed')}
/>
A full-width pill-shaped primary action button. Supports visual feedback via built-in press opacity and an optional disabled state. Used for CTA actions such as “Book Appointment”, “Sign In”, and “Continue”.
| Prop | Type | Default | Description |
|---|
title | string | — | Button label text |
bgc | string | colors.primary | Background color |
textColor | string | colors.secondary | Label text color |
onPress | function | — | Callback fired on press |
disabled | boolean | false | Disables interaction when true |
size | number | fonts.md | Font size for the label |
import FocusButton from '../components/FocusButton';
import { colors } from '../theme/colors';
import { fonts } from '../theme/fonts';
<FocusButton
title="Book Appointment"
bgc={colors.primary}
textColor={colors.secondary}
size={fonts.sm}
onPress={() => navigation.navigate('Booking')}
/>
Pass disabled={true} to prevent double-submission during async operations such as API calls. The button does not apply a reduced-opacity style automatically when disabled — combine with a conditional bgc if you need a visual indicator.
A circular button sized via commonStyles.iconButton (60 × 60, borderRadius: 30) that renders a FontAwesome icon. Used on the authentication screens as OAuth provider shortcuts (Google, Facebook).
| Prop | Type | Default | Description |
|---|
iconName | string | — | FontAwesome icon name — 'google' or 'facebook' |
redirect | function | — | onPress callback, e.g. to launch an OAuth flow |
import IconButton from '../components/IconButton';
<IconButton
iconName="google"
redirect={() => handleGoogleSignIn()}
/>
<IconButton
iconName="facebook"
redirect={() => handleFacebookSignIn()}
/>
A heart icon button that reads doctor.isFavorite to switch between 'heart' and 'heart-outline' icons and dispatches the toggleFavorite Redux thunk on press. Requires the Redux store to be in scope.
| Prop | Type | Default | Description |
|---|
size | number | — | Diameter of the circular button |
bgc | string | colors.shade | Circle background color |
doctor | object | — | Doctor object; must include id and isFavorite (boolean) |
import FavoriteButton from '../components/FavoriteButton';
import { colors } from '../theme/colors';
import { scale } from '../theme/metrics';
<FavoriteButton
size={scale(40)}
bgc={colors.secondary}
doctor={{ id: 'doc_01', isFavorite: false }}
/>
FavoriteButton calls useDispatch() internally. The component must be rendered inside a Redux <Provider> and the DoctorSlice must be present in the store.
A styled text input built on top of react-native-paper’s TextInput. Applies the app’s commonStyles.input shape — shadeLight background, 13 dp corner radius — and hides the default underline to match the SkinFirts flat UI style. Used for email, name, and search fields across auth and profile screens.
| Prop | Type | Default | Description |
|---|
value | string | null | Controlled input value |
onChangeText | function | — | Change handler |
placeholder | string | 'example@example.com' | Placeholder text (rendered in colors.shadeText) |
radius | number | scale(13) | Override border radius |
import InputBox from '../components/InputBox';
const [email, setEmail] = React.useState('');
<InputBox
value={email}
onChangeText={setEmail}
placeholder="Enter your email"
/>
PasswordBox
A react-native-paper TextInput configured for password entry with an eye / eye-off toggle icon that controls secureTextEntry. Manages its own show/hide state internally so no external state for visibility is needed.
| Prop | Type | Default | Description |
|---|
value | string | null | Controlled input value |
onChangeText | function | {} | Change handler |
import PasswordBox from '../components/PasswordBox';
const [password, setPassword] = React.useState('');
<PasswordBox
value={password}
onChangeText={setPassword}
/>
IconicSearchBar
A horizontally laid-out search bar with a SearchIcon SVG on the right and a SliderIcon SVG (inside a white pill) on the left. The TextInput is uncontrolled internally — the component lifts the value up via the setSearch setter.
| Prop | Type | Default | Description |
|---|
setSearch | function | — | State setter (onChangeText target), e.g. React.useState setter |
import IconicSearchBar from '../components/IconicSearchBar';
const [search, setSearch] = React.useState('');
<IconicSearchBar setSearch={setSearch} />
Cards & Info Boxes
MiniCard
A horizontal doctor summary card combining a circular doctor photo, a DetailsBox (name + department), star rating, review count, a help icon, and a FavoriteButton. Used in list views such as the doctor search results and favorites screens.
| Prop | Type | Default | Description |
|---|
doctor | object | — | Doctor record; must include ratings, reviews, and isFavorite |
img | ImageSource | — | Local or remote image source passed to <Image source={...}> |
doctorName | string | — | Display name rendered in the DetailsBox |
department | string | — | Specialty / department text |
import MiniCard from '../components/MiniCard';
const doctor = {
id: 'doc_01',
ratings: 4.9,
reviews: 320,
isFavorite: true,
};
<MiniCard
doctor={doctor}
img={require('../assets/images/doctor1.png')}
doctorName="Dr. Olivia Turner"
department="Dermatology"
/>
IconInfoBox
A compact pill-shaped row that pairs an Ionicons icon with a text label. Used inside MiniCard to display ratings, review counts, and availability badges.
| Prop | Type | Default | Description |
|---|
name | string | — | Ionicons icon name |
size | number | — | Bounding size; icon renders at size * 0.6 |
details | string | number | — | Label rendered next to the icon |
color | string | colors.primary | Icon and text color |
bgc | string | colors.secondary | Pill background color |
textSize | number | fonts.xxs | Font size for details |
onPress | function | — | Optional press handler |
import IconInfoBox from '../components/IconInfoBox';
import { scale } from '../theme/metrics';
<IconInfoBox
name="star-outline"
size={scale(20)}
details={4.9}
color={colors.primary}
bgc={colors.shadeLight}
/>
TextPill
A rounded pill-shaped pressable label used for tag and option selection (e.g. specialty filters, time-slot chips). Text longer than 17 characters is automatically truncated to 15 characters with an ellipsis.
| Prop | Type | Default | Description |
|---|
details | string | — | Pill label text (truncated to 15 chars if over 17) |
textSize | number | fonts.sm | Font size |
bgc | string | colors.primary | Background fill color |
color | string | colors.secondary | Text color |
brc | string | colors.primary | Border color |
onPress | function | — | Callback fired on press |
import TextPill from '../components/TextPill';
import { colors } from '../theme/colors';
import { fonts } from '../theme/fonts';
<TextPill
details="Dermatology"
bgc={colors.shadeLight}
color={colors.primary}
brc={colors.shade}
textSize={fonts.xs}
onPress={() => setSelectedSpecialty('Dermatology')}
/>
ChatBubble
A single chat message bubble that aligns itself to the right for sent messages and to the left for received messages. Sender bubbles use colors.shade with a squared bottom-right corner; receiver bubbles use colors.shadeLight with a squared bottom-left corner.
| Prop | Type | Default | Description |
|---|
isSender | boolean | — | true aligns right (sent); false aligns left (received) |
text | string | — | Message body text |
time | string | — | Timestamp displayed below the bubble |
import ChatBubble from '../components/ChatBubble';
// Received message
<ChatBubble
isSender={false}
text="Hello! How can I help you today?"
time="9:01 AM"
/>
// Sent message
<ChatBubble
isSender={true}
text="I have a question about my prescription."
time="9:02 AM"
/>
Schedule
ScheduleCard
A self-contained schedule widget composed of a horizontal DateStrip date picker and a ScheduleTimeline that lists hourly appointment slots for the selected date. The component manages its own selectedDate state, defaulting to day 11. It is rendered on the Home screen to give patients a quick overview of upcoming appointments.
The card renders against a colors.shade background and does not accept external props — both the date list and hours list are statically defined inside the component. To integrate dynamic data, replace the internal dates and hours arrays with data sourced from your Redux store or API layer.
import ScheduleCard from '../components/ScheduleCard';
// Drop directly onto any screen — no props required
<ScheduleCard />
Navigation & Layout
A screen header component that includes a back-chevron button (via react-navigation’s useNavigation), a centred title, and an optional row of RoundButtons on the right. Safe-area top insets are applied automatically via react-native-safe-area-context. Also supports an optional info prop that renders a “News” badge pill on the right.
| Prop | Type | Default | Description |
|---|
title | string | — | Screen title rendered in the centre |
buttons | array | — | Array of action button descriptors — each object must have an icon key (Ionicons name) |
bgc | string | colors.secondary | Header background color |
color | string | colors.primary | Title and icon tint color |
info | any | — | When truthy, renders a “News” badge pill alongside the right-side buttons |
import CustomHeader from '../components/CustomHeader';
import { colors } from '../theme/colors';
// Basic header with no action buttons
<CustomHeader title="My Appointments" />
// Header with action buttons on the right
<CustomHeader
title="Doctor Profile"
buttons={[
{ icon: 'share-outline' },
{ icon: 'ellipsis-vertical-outline' },
]}
color={colors.primary}
bgc={colors.secondary}
/>
Payment
PaymentOption
A full-width pressable row that represents a single payment method. It combines a RoundButtons icon, a text label, and a react-native-paper RadioButton. Optionally navigates to another screen via redirect after calling onPress.
| Prop | Type | Default | Description |
|---|
name | string | — | Payment method display label |
iconName | string | — | Ionicons icon name for the leading icon button |
value | string | — | Value passed to the RadioButton (should match a RadioButton.Group value) |
onPress | function | — | Callback fired before any navigation |
redirect | string | — | Screen name to navigate to after onPress |
marginBottom | number | verticalScale(12) | Bottom margin applied to the row container |
import PaymentOption from '../components/PaymentOption';
import { RadioButton } from 'react-native-paper';
const [paymentMethod, setPaymentMethod] = React.useState('card');
<RadioButton.Group
onValueChange={setPaymentMethod}
value={paymentMethod}
>
<PaymentOption
name="Credit / Debit Card"
iconName="card-outline"
value="card"
onPress={() => setPaymentMethod('card')}
/>
<PaymentOption
name="PayPal"
iconName="logo-paypal"
value="paypal"
onPress={() => setPaymentMethod('paypal')}
/>
</RadioButton.Group>