<commit_before>var React = require('react');
var ReactDOM = require('react-dom');
var Prismic = require('prismic.io');
import FlipMove from 'react-flip-move';

var tag,
breed;

const breedEnterAnimation = {
    from: { transform: 'scale(0.8)', opacity: 0 },
    to:   { transform: '', opacity: '' }
}
const breedLeaveAnimation = {
	from: { transform: 'scale(1)', opacity: 1 },
    to:   { transform: 'scale(0.8)', opacity: 0 }
}

var DogBreedItem = React.createClass({
	render: function() {
		var breed = this.props.breed;
		var breedImgSrc = (breed.data['breed.image'] ? breed.data['breed.image'].value.views.icon.url : null);
		return (<li>
			<img
				src={breedImgSrc}
			/>
			<h1>{breed.data['breed.name'].value[0].text}</h1>
			<h3>{breed.tags[0]}</h3>
		</li>);
	}
});

var Filters = React.createClass({
	handleChange: function(e) {
		var stateGroup;
		if (e.currentTarget.name == "group") {
			if (e.currentTarget.checked) {
				// use input value if
				stateGroup = e.currentTarget.value;
			} else {
				stateGroup = '';
			}
		} else {
			// use app state as fallback
			stateGroup = this.props.filterGroup;
		}

		this.props.onUserInput(
			this.refs.filterSearchInput.value,
			stateGroup
		);
	},
	render: function() {
		// Prismic uses tags, but for users we'll call these "groups"
		var groups = [];
		for (let tag of this.props.tags) {
			groups.push(
				<span key={tag} className="filter--group">
					<input
						type="checkbox"
						name="group"
						id={"group" + tag}
						ref="filterGroupInput"
						checked={this.props.filterGroup === tag}
						onChange={this.handleChange}
						value={tag}
						/>
					<label htmlFor={"group" + tag}>
						{tag}
					</label>
				</span>
			);
		}
		return (
			<form>
				<h3>Filter by Group</h3>
				{groups}
				<h3>Or Search for your Dog</h3>
				<input
					className="filter--search"
					type="text"
					placeholder="Search..."
					value={this.props.filterSearch}
					ref="filterSearchInput"
					onChange={this.handleChange}
					/>
			</form>
		);
	}
});

var FilterableDogApp = React.createClass({
	getInitialState: function() {
		return {
			filterSearch: '',
			filterGroup: ''
		};
	},
	handleUserInput: function(filterSearch, filterGroup) {
		this.setState({
			filterSearch: filterSearch,
			filterGroup: filterGroup
		});
	},
	render: function() {
		var breedItems = [];
		var tagList    = [];

		// for each result
		for (let result of this.props.data.results) {
			var breed = {};
			breed.name = result.data['breed.name'].value[0].text;
			breed.tag  = result.tags[0];

			// Add breed to breedItems if it passes filtering
			if (breed.name.toLowerCase().indexOf(this.state.filterSearch.toLowerCase()) !== -1 && breed.tag.indexOf(this.state.filterGroup) !== -1) {
				breedItems.push(<DogBreedItem breed={result} key={breed.name}/>);
			}

			// Add tag to tagList if it's not already in there
			if (tagList.indexOf(breed.tag) == -1) {
				tagList.push(breed.tag);
			}
		}
		return (
			<div>
				<Filters
					tags={tagList}
					filterGroup={this.state.filterGroup}
					filterSearch={this.state.filterSearch}
					onUserInput={this.handleUserInput}
					/>
				<FlipMove
					enterAnimation={breedEnterAnimation}
					leaveAnimation={breedLeaveAnimation}
					typeName="ul"
					className="list--breeds"
					staggerDurationBy="15"
					staggerDelayBy="20"
					easing="ease"
					>
					{breedItems}
				</FlipMove>
			</div>
		);
	}
});

// Request content
Prismic.api("https://dogdaze.prismic.io/api").then(function(api) {
	return api.query(""); // An empty query will return all the documents
}).then(function(prismicDocuments) {
	console.log(prismicDocuments);
	// Render app
	ReactDOM.render(
		<FilterableDogApp data={prismicDocuments} />,
		document.querySelector('.container--app')
	);
}, function(err) {
	console.log("Something went wrong: ", err);
});
<commit_msg>possible linked functionality between grid-level tags and app-level filters<commit_after>var React = require('react');
var ReactDOM = require('react-dom');
var Prismic = require('prismic.io');
import FlipMove from 'react-flip-move';

var tag,
breed;

const breedEnterAnimation = {
    from: { transform: 'scale(0.8)', opacity: 0 },
    to:   { transform: '', opacity: '' }
}
const breedLeaveAnimation = {
	from: { transform: 'scale(1)', opacity: 1 },
    to:   { transform: 'scale(0.8)', opacity: 0 }
}

var DogBreedItem = React.createClass({
	render: function() {
		var breed = this.props.breed;
		var breedImgSrc = (breed.data['breed.image'] ? breed.data['breed.image'].value.views.icon.url : null);
		return (<li>
			<img
				src={breedImgSrc}
			/>
			<h1>{breed.data['breed.name'].value[0].text}</h1>
			<h3><label htmlFor={"group" + breed.tags[0]}>{breed.tags[0]}</label></h3>
		</li>);
	}
});

var Filters = React.createClass({
	handleChange: function(e) {
		var stateGroup;
		if (e.currentTarget.name == "group") {
			if (e.currentTarget.checked) {
				// use input value if
				stateGroup = e.currentTarget.value;
			} else {
				stateGroup = '';
			}
		} else {
			// use app state as fallback
			stateGroup = this.props.filterGroup;
		}

		this.props.onUserInput(
			this.refs.filterSearchInput.value,
			stateGroup
		);
	},
	render: function() {
		// Prismic uses tags, but for users we'll call these "groups"
		var groups = [];
		for (let tag of this.props.tags) {
			groups.push(
				<span key={tag} className="filter--group">
					<input
						type="checkbox"
						name="group"
						id={"group" + tag}
						ref="filterGroupInput"
						checked={this.props.filterGroup === tag}
						onChange={this.handleChange}
						value={tag}
						/>
					<label htmlFor={"group" + tag}>
						{tag}
					</label>
				</span>
			);
		}
		return (
			<form>
				<h3>Filter by Group</h3>
				{groups}
				<h3>Or Search for your Dog</h3>
				<input
					className="filter--search"
					type="text"
					placeholder="Search..."
					value={this.props.filterSearch}
					ref="filterSearchInput"
					onChange={this.handleChange}
					/>
			</form>
		);
	}
});

var FilterableDogApp = React.createClass({
	getInitialState: function() {
		return {
			filterSearch: '',
			filterGroup: ''
		};
	},
	handleUserInput: function(filterSearch, filterGroup) {
		this.setState({
			filterSearch: filterSearch,
			filterGroup: filterGroup
		});
	},
	render: function() {
		var breedItems = [];
		var tagList    = [];

		// for each result
		for (let result of this.props.data.results) {
			var breed = {};
			breed.name = result.data['breed.name'].value[0].text;
			breed.tag  = result.tags[0];

			// Add breed to breedItems if it passes filtering
			if (breed.name.toLowerCase().indexOf(this.state.filterSearch.toLowerCase()) !== -1 && breed.tag.indexOf(this.state.filterGroup) !== -1) {
				breedItems.push(<DogBreedItem breed={result} key={breed.name}/>);
			}

			// Add tag to tagList if it's not already in there
			if (tagList.indexOf(breed.tag) == -1) {
				tagList.push(breed.tag);
			}
		}
		return (
			<div>
				<Filters
					tags={tagList}
					filterGroup={this.state.filterGroup}
					filterSearch={this.state.filterSearch}
					onUserInput={this.handleUserInput}
					/>
				<FlipMove
					enterAnimation={breedEnterAnimation}
					leaveAnimation={breedLeaveAnimation}
					typeName="ul"
					className="list--breeds"
					staggerDurationBy="15"
					staggerDelayBy="20"
					easing="ease"
					>
					{breedItems}
				</FlipMove>
			</div>
		);
	}
});

// Request content
Prismic.api("https://dogdaze.prismic.io/api").then(function(api) {
	return api.query(""); // An empty query will return all the documents
}).then(function(prismicDocuments) {
	console.log(prismicDocuments);
	// Render app
	ReactDOM.render(
		<FilterableDogApp data={prismicDocuments} />,
		document.querySelector('.container--app')
	);
}, function(err) {
	console.log("Something went wrong: ", err);
});

{'fraction_non_alphanumeric': 0.16342115311187477, 'fraction_numerical': 0.007000127275041365, 'mean_word_length': 3.1445147679324896, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 57, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '874640', 'n_tokens_mistral': 3261, 'n_tokens_neox': 2669, 'n_words': 524}